TeX (pronounced like "tech") is a typesetting system, which is still used for writing research papers in Mathematics, Computer Science, Physics, and related disciplines, and pretty much nothing else. Everyone else moved on to either WYSIWYG editors like Word, or to HTML, or maybe Markdown or something like that. But it still survives in its niche.
Like every typesetting system, it comes with its own embedded programming language, and that's what we're going to use.
Technically TeX is just the original system, and we'll also be using a lot of *TeX things (MacTeX, LaTeX, pdftex etc.), but that's meaningless distinction, so I won't mention it anymore.
Hello, World!
\documentclass{minimal}
\newcommand\hello[1]{Hello, #1!}
\begin{document}
\hello{World}
\end{document}
Which with pdflatex hello.tex
generates a PDF page with the text "Hello, World!" (only relevant part shown):
What's going on here:
-
\documentclass{minimal}
defines the kind of document we're making - as we're not really interested in any typesetting, we can just useminimal
. The most common type for actual documents would bearticle
. - then follows basically equivalent of HTML
<head>
part -
\begin{document} ... \end{document}
is like HTML<body> ... </body>
- We define
\hello
command with\newcommand\hello[1]{Hello, #1!}
- the[1]
says it takes one argument, then in the function body#1
refers to that argument. - We call the function with
\hello{World}
- there are no parentheses here, we defined explicitly it takes exactly one argument.
Loop
Let's try to setup a loop from 11 to 20. Obviously the system comes with lists already (numbered with \begin{enumerate} \item A \item B \end{enumerate}
, bulleted with \begin{itemize} \item A \item B \end{itemize}
, and all the other usual kinds), but we'll be doing a FizzBuzz shortly.
\documentclass{minimal}
\setlength{\parindent}{0pt}
\usepackage{ifthen}
% \numberloop{A}{B} prints all numbers from A to B
\newcommand\numberloop[2]{
\newcounter{i}
\setcounter{i}{#1}
\whiledo{\not{\value{i}>#2}}
{
\thei
\ifthenelse{\equal{#2}{\thei}}{.}{,}
\stepcounter{i}
}
}
\begin{document}
\numberloop{10}{100}
\end{document}
Which generates this:
What's going on:
- TeX has annoying default of having paragraph indent, we need to get rid of it with
\setlength{\parindent}{0pt}
- we import a package called
ifthen
with\usepackage{ifthen}
- it contains some control structures\ifthenelse
and\whiledo
-
%
indicates line comments - we define command
\numberloop
that takes two arguments - inside it we define integer variable ("counter")
i
and set it to#1
(first passed argument) - there's nothing like
... <= ...
in a loop, so loop condition must be\not{... > ...}
(or +1 one of the sides) - inside the loop body,
\thei
means "current value ofi
counter" -
\ifthenelse{\equal{#2}{\thei}}{.}{,}
prints appropriate separator -,
normally, but.
in the final iteration. -
\stepcounter{i}
increases counteri
by1
each time
FizzBuzz
\documentclass{minimal}
\setlength{\parindent}{0pt}
\usepackage{ifthen}
\usepackage{intcalc}
\usepackage{multicol}
% \fizzbuzz{N} prints Fizz, Buzz, FizzBuzz, or N, according to the usual rules
\newcommand\fizzbuzz[1]{
\ifthenelse{\equal{\intcalcMod{#1}{15}}{0}}{FizzBuzz}{
\ifthenelse{\equal{\intcalcMod{#1}{5}}{0}}{Buzz}{
\ifthenelse{\equal{\intcalcMod{#1}{3}}{0}}{Fizz}{#1}
}
}
}
% \fizzbuzzloop{A}{B} prints all FizzBuzz entries from A to B
\newcommand\fizzbuzzloop[2]{
\newcounter{i}
\setcounter{i}{#1}
\whiledo{\not{\value{i}>#2}}
{
\fizzbuzz{\thei}
\linebreak
\stepcounter{i}
}
}
\begin{document}
\begin{multicols}{4}
\fizzbuzzloop{1}{100}
\end{multicols}
\end{document}
Which generates this:
A few things are going on here:
- we import package for integer math
\usepackage{intcalc}
- we import package for multi-column layout
\usepackage{multicol}
-
\fizzbuzz{N}
does the FizzBuzz for one number -
\fizzbuzzloop{A}{B}
does the FizzBuzz for all numbers from A to B, with line breaks in between - we wrap it all in a 4-column layout so the screenshot looks better
Fibonacci
\documentclass{minimal}
\setlength{\parindent}{0pt}
\usepackage{ifthen}
\usepackage{intcalc}
% \fib{N} returns the Nth Fibonacci number
\newcounter{j}
\newcounter{fiba}
\newcounter{fibb}
\newcounter{fibc}
\newcommand\fib[1]{
\setcounter{j}{1}
\setcounter{fiba}{1}
\setcounter{fibb}{1}
\whiledo{\value{j} < #1}
{
\setcounter{fibc}{\intcalcAdd{\thefiba}{\thefibb}}
\setcounter{fiba}{\thefibb}
\setcounter{fibb}{\thefibc}
\stepcounter{j}
}
\thefiba
}
% \fibloop{A}{B} prints all Fibonacci numbers from A to B
\newcommand\fibloop[2]{
\newcounter{i}
\setcounter{i}{#1}
\whiledo{\not{\value{i}>#2}}
{
\fib{\thei}
\linebreak
\stepcounter{i}
}
}
\begin{document}
\raggedright
\fibloop{1}{20}
\end{document}
Which generates this:
TeX has serious problems with recursion, so we do a loop calculation instead. Oh and while previous code might have implied that \newcounter
variables are local - they are all completely global, except for #1
etc. arguments.
Should you use TeX?
Only if you're forced to by your journal. Otherwise no, it's completely obsolete.
Historically its primary strength was math. In particular, supporting made-up mathematical notation each researcher would come up with (the normal notation was supported by everything anyway). But nowadays, other systems can do that too. For everything else, TeX was never good.
TeX also seems to largely abandoning its existing programming language and embedding much saner Lua instead.
Even as an esoteric programming language, TeX's programming language doesn't really do anything too interesting. If you want a fun challenge, writing Postscript is likely to provide a lot better one.
Code
All code examples for the series will be in this repository.
Top comments (1)
I think you're wrong about obsolescence
Well, half wrong.
It's as old as it gets and was painful even first time I saw it 30 years ago.
But nothing better came along for scientific typesetting, and it's still widely used in academia