9

I would like to know how the \maketitle command works since I am creating my own class and I want to use my own commands. For example, I already create certain commands like \a, \b and \c and I want that with a certain command we say \printabc a new page is created printing such commands.

Thanks in advance

EDIT 1: I try to define

\def\@mycover{%
    \newpage\null
}

but get the error

! Use of \@ doesn't match its definition.

EDIT 2: I have made progress.

\documentclass{myclass}

\makeatletter
\newcommand*{\mytitle}[1]{\gdef\@mytitle{\MakeUppercase{#1}}}
\newcommand*{\myauthors}[5]{\gdef\@myauthors{
    \begin{tabular}{c}
        \MakeUppercase{#1} \\ 
        \MakeUppercase{#2} \\  
        \MakeUppercase{#3} \\
        \MakeUppercase{#4} \\
        \MakeUppercase{#5}
    \end{tabular}
}}
\newcommand*{\myafil}[5]{\gdef\@myafil{
    \begin{tabular}{c}
        \MakeUppercase{#1} \\ 
        \MakeUppercase{#2} \\  
        \MakeUppercase{#3} \\
        \MakeUppercase{#4} \\
        \MakeUppercase{#5}
    \end{tabular}
}}
\newcommand\makecover{\begin{titlepage}%
    \thispagestyle{empty}\centering\bfseries
    \@mytitle
    \vfill
    \@myauthors
    \vfill
    \@myafil
\end{titlepage}
\global\let\makecover\relax
\global\let\@mytitle\@empty
\global\let\@myauthors\@empty
\global\let\@myafil\@empty
\global\let\mytitle\relax
\global\let\myauthors\relax
\global\let\myafil\relax
}
\makeatother

\mytitle{The Title}
\myauthors{Author 1}{}{}{}{}
\myafil{University}{Faculty of exact and natural sciences}{Department of Mathematics}{City}{Year}

\begin{document}
\makecover
\end{document}

This is all right, but when I comment for example

%\myauthors{Author 1}{}{}{}{}

the following error arises

! Undefined control sequence.

something that does not happen in class book. why does that happen?

Joan
  • 479
  • 2
    Basically, for example, the \author command does \gdef\@author{<Something>}, then \maketitle contains \@author, which will print <Something>. I suggest looking at LaTeX's base classes for some guidance: https://www.tug.org/svn/texlive/trunk/Master/texmf-dist/tex/latex/base/article.cls?view=co – Phelype Oleinik Sep 28 '18 at 17:44
  • 2
    To use commands with @ in their name you have to say \makeatletter before. See What do \makeatletter and \makeatother do? – Phelype Oleinik Sep 28 '18 at 18:00
  • Thanks, so the command \newcommand*{\mytitle}[1]{\gdef\@mytitle{#1}} needs \makeatletter? – Joan Sep 28 '18 at 18:12
  • 1
    Not inside the \newcommand, but before it. But if you are writing a class in a .cls file the \makeatletter thingy should already be active. If you are testing outside the .cls file then yes, you need the \makeatletter. – Phelype Oleinik Sep 28 '18 at 18:14
  • Shure, \makeatletter\newcommand...\makeatother. Thanks, i will try it – Joan Sep 28 '18 at 18:17
  • In the book.cls file, I see that they define two commands, namely, \maketitle and \@maketitle, so, why its that? what is the diference? – Joan Sep 28 '18 at 18:19
  • 2
    The \maketitle command is what the user will use. The \@maketitle is an implementation detail. It could be called (non intuitively) \@potato :P But in this case, the \@maketitle holds the actual formatting of the title and is called differently by \maketitle in case the twocolumn option is used. – Phelype Oleinik Sep 28 '18 at 18:23
  • 1
    It's a really bad idea to edit your question to include another one. I suggest you ask a new question instead. But the error you get is because if you don't call the \myauthors command then the \@myauthors macro will never be defined, then TeX will complain that is is Undefined. You can add \def\@myauthors{} in your class file so you are sure that the macro exists. Or you can use the same approach as LaTeX and do \def\@myauthors{\@latex@warning@no@line{No \noexpand\myauthor given}}. Off-topic: I would go for a comma separated list of authors instead of {}{}{}{}{}... – Phelype Oleinik Sep 28 '18 at 20:16
  • Thanks for the first advice. So, \def\@myauthors{\@latex@warning@no@line{No \noexpand\myauthor given}}\newcommand*{\mytitle}[1]{\gdef\@mytitle{\MakeUppercase{#1}}} is the correct form? and... how do I make the command understand that the arguments are the entries separated by commas? – Joan Sep 28 '18 at 20:31
  • 1
    By saying \def\@myauthors{\@latex@warning@no@line{No \noexpand\myauthor given}} you tell LaTeX to raise a (comprehensible) error if the user of the class doesn't provide an author. Alternatively you can use \def\@myauthors{} then, if the author doesn't use \myauthors, an empty string will be used. As for the comma thing, it's way more complicated than just using a \newcommand. New Question ;) – Phelype Oleinik Sep 28 '18 at 20:35
  • jeje, thanks again. I create a new post https://tex.stackexchange.com/questions/453007/command-with-arguments-separated-by-comma – Joan Sep 28 '18 at 21:05

1 Answers1

11

Let's assume you're basing your document class on the article document class. The following definition of \maketitle applies if the titlepage document class option was not set:

\newcommand\maketitle{\par
  \begingroup
    \renewcommand\thefootnote{\@fnsymbol\c@footnote}%
    \def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}%
    \long\def\@makefntext##1{\parindent 1em\noindent
            \hb@xt@1.8em{%
                \hss\@textsuperscript{\normalfont\@thefnmark}}##1}%
    \if@twocolumn
      \ifnum \col@number=\@ne
        \@maketitle
      \else
        \twocolumn[\@maketitle]%
      \fi
    \else
      \newpage
      \global\@topnum\z@   % Prevents figures from going at top of page.
      \@maketitle
    \fi
    \thispagestyle{plain}\@thanks
  \endgroup
  \setcounter{footnote}{0}%
  \global\let\thanks\relax
  \global\let\maketitle\relax
  \global\let\@maketitle\relax
  \global\let\@thanks\@empty
  \global\let\@author\@empty
  \global\let\@date\@empty
  \global\let\@title\@empty
  \global\let\title\relax
  \global\let\author\relax
  \global\let\date\relax
  \global\let\and\relax
}

What's going on? The macro consists mainly of two parts.

  • In the first part, i.e., the material that's sandwiched between \begingroup and \endgroup, we begin by resetting how footnotes are typeset; mostly, symbolic markers (asterisks, daggers, etc) are used as footnote markers instead of numerals. Next, LaTeX checks if the twocolumn document class was set; if the answer is "no", the \newpage instruction is executed, followed by \@maketitle. (The contents of \@maketitle are examined in more detail below.)

  • In the second part, the footnote counter is (re)set to 0, and then the macros \thanks, \maketitle, \@maketitle, \@thanks, \@author, \@date, \@title, \title, \author, \date, and \and -- which are all defined in the LaTeX kernel -- are all unset. The \global qualifiers are needed, as otherswise the \let\xyz\relax directives would not apply outside of the current group, which was started by the \begingroup directive mentioned above.

The upshot: The macros \title, \author, \date can not be used again once \maketitle has been run. What's the purpose of unsetting these macros, you may ask? If nothing else, this step makes sure that one cannot -- accidentally or intentionally -- run \maketitle more than once in a document.

Finally, how is the macro \@maketitle defined? In article.cls, one finds the following code:

\def\@maketitle{%
  \newpage
  \null
  \vskip 2em%
  \begin{center}%
  \let \footnote \thanks
    {\LARGE \@title \par}%
    \vskip 1.5em%
    {\large
      \lineskip .5em%
      \begin{tabular}[t]{c}%
        \@author
      \end{tabular}\par}%
    \vskip 1em%
    {\large \@date}%
  \end{center}%
  \par
  \vskip 1.5em}

The bulk of the code occurs between \begin{center} and \end{center}: The argument of \title, which gets typeset via \@title, is set at the \LARGE font size (72.7% larger than \normalsize); the argument of \author gets typeset inside a 1-column tabular environment, in \large (20% larger than \normalsize); and the argument of \date (if any) also gets typeset in \large. The center environment ends and a vertical skip of 1.5em is inserted. Importantly, no page break is inserted. Thus, if the next document element is the abstract environment, LaTeX will try to fit the abstract on the page that already contains the title, author, and date elements.

Mico
  • 506,678
  • 1
    Is it possible to remove the vskip 2em parameter? – ifly6 Sep 14 '20 at 05:55
  • @ifly6 - Certainly. Actually, what's really needed is to remove the \null instruction that precedes \vskip 2em. To do this, I suggest you load the etoolbox package and run the following instructions in the preamble: \makeatletter \patchcmd{\@maketitle}{\null}{}{}{} \makeatother. – Mico Jun 07 '22 at 10:33