TeX Notes
Table of Contents
1. Introduction
These are random observations about TeX and LaTeX. Remember:
- 6 pica = 1inch
- 8.5 inches = 51 pica
- 11 inches = 66 pica.
2. Poor Man's LaTeX
I've been curious about how LaTeX is built out of TeX macros for a while now. These are just some observations about it.
2.1. Environments
Someone asked on tex.stackexchange about how environments in LaTeX are
implemented using only plain TeX. David Carlisle's answer was quite
enlightening: \begin{foo}
executes \foo
, and \end{foo}
executes
\endfoo
. But this requires redefining plain TeX's \end
primitive,
setting it to be \@@end
in LaTeX.
This sparked a curiousity about LaTeX's implementation details. They can
be found, for texlive users, in
/usr/share/texlive/texmf-dist/tex/latex-dev/base/latex.ltx
or somewhere
similar.
If one imitates LaTeX, and writes something like \let\@@end\end
, then
one needs to redefine \bye
to be something like:
\def\makeatletter{\catcode`\@11\relax} \def\makeatother{\catcode`\@12\relax} \makeatletter \let\@@end\end \outer\def\bye{\par\vfill\supereject\@@end} % define environment syntax \def\begin#1{\begingroup\csname#1\endcsname} \def\end#1{\csname end#1\endcsname\endgroup} \makeatother
2.1.1. What LaTeX does
In latex.ltx
around lines 4400, we find
\DeclareRobustCommand\begin[1]{% \@ifundefined{#1}% {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% {\def\reserved@a{\def\@currenvir{#1}% \edef\@currenvline{\on@line}% \csname #1\endcsname}}% \@ignorefalse \begingroup\@endpefalse\reserved@a} \edef\end {\unexpanded{% \romannumeral \ifx\protect\@typeset@protect \expandafter %1 \expandafter %2 \expandafter %1 \expandafter %3 expands the \csname inside \end<space> \expandafter %1 \expandafter %2 expands \end<space> \expandafter %1 expands the \else \z@ \else \expandafter\z@\expandafter\protect \fi }% \expandafter\noexpand\csname end \endcsname } \@namedef{end }#1{% \csname end#1\endcsname\@checkend{#1}% \expandafter\endgroup\if@endpe\@doendpe\fi \if@ignore\@ignorefalse\ignorespaces\fi} \def\@checkend#1{\def\reserved@a{#1}\ifx \reserved@a\@currenvir \else\@badend{#1}\fi} \let\@currenvline\@empty % ... % 4907: \def\@doendpe{\@endpetrue \def\par{\@restorepar \clubpenalty\@clubpenalty \everypar{}\par\@endpefalse}\everypar {{\setbox\z@\lastbox}% \everypar{}\@endpefalse}}
2.2. Equations
The implementation is fairly straightforward.
%% LaTeX's implementation: %% %% \def\stepcounter#1{% %% \addtocounter{#1}\@ne %% \begingroup %% \let\@elt\@stpelt %% \csname cl@#1\endcsname %% \endgroup} %% \def\@definecounter#1{\expandafter\newcount\csname c@#1\endcsname %% \setcounter{#1}\z@ %% \global\expandafter\let\csname cl@#1\endcsname\@empty %% \@addtoreset{#1}{@ckpt}% %% \global\expandafter\let\csname p@#1\endcsname\@empty %% \expandafter %% \gdef\csname the#1\expandafter\endcsname\expandafter %% {\expandafter\@arabic\csname c@#1\endcsname}} \def\stepcounter#1{ \expandafter\global\expandafter\advance\csname c@#1\endcsname by1 } \def\setcounter#1#2{ \expandafter\global\csname c@#1\endcsname=#2 } \def\@definecounter#1{ \expandafter\newcount\csname c@#1\endcsname \setcounter{#1}{0} \expandafter \gdef\csname the#1\expandafter\endcsname\expandafter {\expandafter\number\csname c@#1\endcsname} } \@definecounter{equation} \def\equation{$$\refstepcounter{equation}} \def\endequation{\eqno \hbox{\@eqnnum}$$\@ignoretrue} \def\@eqnnum{{\normalfont \normalcolor (\theequation)}}
3. Math Gallery
3.1. Normal Ordering Operators
In Quantum Field Theory (and Vertex Operator Algebras, and related subjects), we need normal ordering of operators. This has been discussed at least once on tex.stackexchange, and the answers are quite good.
3.2. Tractatus Numbering in Plain TeX
Someone asked for this in plain TeX, and David Carlisle's solution fits my needs perfectly.
\newcount\zzdepth \newcount\zza \edef\zzbase{\the\allocationnumber} \zzdepth\allocationnumber \newcount\zzb \newcount\zzc \newcount\zzd \def\thezz{{% \ifnum\zzdepth>\zzbase\relax \advance\zzdepth-1 % \expandafter\thezz \fi }\the\count\zzdepth.% } \everypar{{\bf\thezz} } \def\on{\advance\count\zzdepth 1\relax} \def\eatstar*{} \def\down{\futurelet\tmp\xxdown} \def\xxdown{% \ifx*\tmp \advance\zzdepth 1 \count\zzdepth 0\relax \expandafter\eatstar \else \advance\zzdepth 1 \count\zzdepth 1\relax \fi} \def\up{\advance\zzdepth -1 \advance\count\zzdepth 1\relax} \on This is the first paragraph, paragraph number 1. \on This is paragraph number 2. \down This is paragraph number 2.1 \down* This is 2.10 \up This is 2.2 \down This is 2.2.1 \up\up This is 3 \bye
I liked this, but wanted to hack something together more suitable for my own personal purposes:
\newcount\zzdepth \newcount\zza \edef\zzbase{\the\allocationnumber} \zzdepth\allocationnumber \newcount\zzb \newcount\zzc \newcount\zzd \def\thezz{{% \ifnum\zzdepth>\zzbase\relax \advance\zzdepth-1 % \expandafter\thezz \fi }\the\count\zzdepth.% } \def\theM{{\bf\thezz}\quad\ignorespaces} \def\None#1{\advance\count\zzdepth 1\relax\theM{\bf#1.}\quad\ignorespaces} \def\Nmany[#1]#2{\advance\zzdepth by#1 \ifnum#1<0\advance\count\zzdepth 1 \else\count\zzdepth 1 \fi\relax {\bf\thezz\ #2.}\quad\ignorespaces} \def\xN{\ifx\tmp[\expandafter\Nmany\else\None\fi} \def\N{\medbreak\noindent\ignorespaces\futurelet\tmp\xN} \def\Mone{\advance\count\zzdepth 1\relax\theM} \def\Mmany[#1]{\advance\zzdepth by#1 \ifnum#1<0\advance\count\zzdepth 1 \else\count\zzdepth 1 \fi\relax\theM} \def\xM{\ifx\tmp[\expandafter\Mmany\else\Mone\fi} \def\M{\medbreak\noindent\ignorespaces\futurelet\tmp\xM} \M Paragraph 1, reporting! \M Paragraph 2, alert! \N[1]{Theorem} {\it Paragraph {2.1} should be present.} \M This is the first paragraph, paragraph number 1. \M This is paragraph number 2. \M[1] This is paragraph number 2.1 \M[1] This is 2.10 \M[-1] This is 2.3.2 \M[1] This is 2.2.1 \M[2] This is, uh, 2.2.1.1.1? \M[-1] Wait, what does this do? \M[-4] This is 3 Spam and eggs test! \bye
3.3. Typing Relation
I noticed that lhs2tex
has some primitive macros which make the
resulting LaTeX look nice. In particular, their typing relation t : T
uses \mathbin{:}
to give us \(t\mathbin{:}T\) as opposed to \(t:T\).
If we wanted a kinding relation, we would use \mathbin{::}
to give us
\(T\mathbin{::}K\) instead of \(T::K\).
I have a hard time noticing any difference between the "before/after" for either situation.
Figure 1: Different variants in the typesetting of the typing relation.
Conceptually we would probably want to use a \mathrel{:}
, but in
practice we would want to use \mathbin{:}
or manually specify the
spacing. The difference is that TeX will squeeze a mathbin, but not a
mathrel, and mathbin has spacing of 4/18em (when unsqueezed) whereas
mathrel has a spacing of 5/18em. If we wanted even less space, we could
use a mathop.
- What is the difference between
\mathbin
vs.\mathrel
? thread on tex.stackexchange is very enlightening
4. Equation Indent
Sometimes it is useful to have equations be indented by the same amount
(as opposed to being centered). This is done using the fleqn
document
option, usually. For the base classes, this introduces a new dimension
\mathindent
, which is equal to the length of the \leftmargini
dimension.
In the article
document class, \leftmargini
is 2em for two-column
documents, and 2.5em for single column documents.
5. AMSPPT
\pagewidth{30pc}\pageheight{50.5pc}
(source)- Text width is 30pc = 5 inches
- Text height is 50.5pc = (8 + (1/3)) inches
- Inner margin appears to be 1 inch
- outer margin appears to be 1 inch(???)
parindent
is 1pc.