
Recién estoy comenzando con LaTeX y ya estoy luchando con las cosas más básicas.
Creo 2 comandos, cada uno asignando un valor a una variable:
\newcommand{\firstname}[1]{\def\@firstname{#1}}
\newcommand{\lastname}[1]{\def\@lastname{#1}}
Estas variables se configuran usando los comandos en algún lugar al principio del documento:
\firstname{Kevin}
\lastname{De Coninck}
Cuando intento imprimir lastname
, todo funciona bien, cuando intento imprimir firstname
, aparece el siguiente errorUse of \@ doesn't match its definition. \@f
Estoy imprimiendo dentro de mi documento usando el siguiente código:
\begin{document}
\@firstname
\end{document}
¿Que me estoy perdiendo aqui?
Actualización: documento completo
% ----------------------------------------------------------------------
% -- 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}
Respuesta1
Agregué el \makeatletter...\makeatother
par habitual en torno a las definiciones y el uso.
Tenga en cuenta también la propuesta de Daleif: \CMPLXfirstname
parece ser mejor y más fácil.
También me he cambiado \RequirePackage
a \usepackage
(aunque el primero también está permitido, pero está destinado únicamente a paquetes, no a documentos normales)
Ahora, @
es un carácter especial que está reservado como parte de los nombres de los comandos internos y que no debería ser fácilmente accesible para un usuario normal de documentos. Fuera de los paquetes o archivos de clase @
no se considera una letra permitida para los nombres de los comandos, por lo que \makeatletter
cambia esto (temporalmente), permitiendo @
ser parte de dichos nombres y \makeatother
lo revierte.
% ----------------------------------------------------------------------
% -- 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}
Respuesta2
En caso de que no desee utilizar \makeatletter
... \makeatother
, puede utilizar
\csname..\endcsname
:
\csname @firstname\endcsname
→ \@firstname
.
\csname @lastname\endcsname
→ \@lastname
.
He escrito un pequeño envoltorio para \csname..\endcsname
:
La macro \CreateCsFromName
funciona de la siguiente manera:
\CreateCsFromName<preceding tokens with no curly braces>{ControlSequence}
→ <preceding tokens with no curly braces>\ControlSequence
.
Si omite <preceding tokens with no curly braces>
, es decir, si lo deja <preceding tokens with no curly braces>
vacío, \CreateCsFromName
simplemente construirá el token de secuencia de control a partir del nombre de la secuencia de control:
\CreateCsFromName{macro}
→ \macro
En lugar de dejarlo <preceding tokens with no curly braces>
vacío, puede proporcionar cualquier comando para (re)definir:
\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}
Ejemplo:
\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}