Skip to content

Latest commit

 

History

History
371 lines (303 loc) · 9.5 KB

tex.org

File metadata and controls

371 lines (303 loc) · 9.5 KB

TeX Notes

Introduction

These are random observations about TeX and LaTeX. Remember:

  • 6 pica = 1inch
  • 8.5 inches = 51 pica
  • 11 inches = 66 pica.

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.

Also see the miniltx package which reproduces a fragment of LaTeX in plain TeX. Also of interest would be eplain (for plain TeX users).

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

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}}

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)}}

Math Gallery

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.

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

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.

../img/typing-relation-article-cls.png

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.

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.

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.