Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to know how does LaTeX invoke the error Missing \begin{document}. I would like to reproduce it in the sense of the following MWE (it will become a part of my own document class):

\documentclass{article}

\begin{document}

\title{My titlE} % <-- these are fine
\author{tohecz}
\def\A{\mathbf{A}}

Hello % <-- should invoke error "Text before `\maketitle` command"
% the error should be invoked even when `\maketitle` is missing at all

\maketitle

World % <-- this is fine

\end{document}
share|improve this question
add comment

1 Answer 1

up vote 16 down vote accepted

LaTeX uses the \everypar token register to set up the error. If you try \showthe\everypar before \begin{document} you will see

> \@nodocument .
l.3 \showthe\everypar

The internal command \@nodocument expands to give the error. This works as TeX inserts \everypar each time it starts a paragraph, and that happens when it encounters horizontal mode material while in vertical mode. TeX starts off in vertical mode, and the first letter or similar causes a switch to horizontal mode, inserts \everypar and thus here fires the error.

Part of the \document macro removes \@nodocument from \everypar. So you want to add something to it, and remove or disable it again as part of \maketitle. You also need to activate that in the right place, at the end of \document. Something like

\makeatletter
\g@addto@macro{\document}{\everypar\expandafter{\the\everypar\my@title@check}}        
\g@addto@macro{\maketitle}{\global\let\my@title@check\relax}
\newcommand*{\my@title@check}{\PackageError{MyPkg}{Missing \protect\maketitle}\@ehc}
\makeatother

Rather than remove the check from \everypar, I've taken the route of simply converting it to a no-op once \maketitle has been used. You could also use a flag, for example if you have further tests to do. (Removing from the toks would require a bit of care for the general case, so I'm avoiding the issue.)

share|improve this answer
    
Ok, so \everypar is the key! I was thinking about \EveryShipout that would invoke the error at the end of the first page, but I was sure LaTeX does not use anything like that. –  tohecz Jun 15 '12 at 9:09
1  
Just please, what does \@ehc do? Does it come from "end document hook"? –  tohecz Jun 15 '12 at 9:10
2  
@tohecz \@ehc is a generic error handler command. I've used \PackageError, which needs two arguments, the first 'error text' and the second 'more error text'. In common with a lot of the LaTeX kernel errors, I've decided I'm not going to write 'more error text' but just use \@ehc to give something generic. –  Joseph Wright Jun 15 '12 at 9:15
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.