Karl Berry recently blogged about creating the following in TeX:
A 6×6 grid of pictures, with a big picture of size 2×2 in the middle. All pictures should be surrounded by a border.
Karl said that he tried pdfpages
package but, in the end, used low-level \halign
. Ouch! Use \halign
. I don’t know how many people who start with LaTeX or ConTeXt actually know the syntax of \halign
. But what I find shocking is that Karl’s next best choice was pdfpages
, a package to combine pdf pages. Is the state of affairs with LaTeX tables so bad?
I tried to achieve that same layout in ConTeXt, and it was really simple.
% Placeholders for figures
\useexternalfigure[photo] [cow] [width=2cm, height=1.5cm]
\useexternalfigure[center][cow] [width=4cm, height=3cm]
\setupTABLE[each][each][framecolor=lightred, rulethickness=3bp, frame=on, strut=off]
\starttext
\startTEXpage
\bTABLE
\bTR
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\eTR
\bTR
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\eTR
\bTR
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD[nr=2,nc=2] \externalfigure[center]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\eTR
\bTR
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\eTR
\bTR
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\eTR
\bTR
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\bTD \externalfigure[photo]\eTD
\eTR
\eTABLE
\stopTEXpage
\stoptext
Notice the [nr=2,nr=2]
for the middle cell. This tells ConTeXt that the middle cell spans 2 rows and 2 columns. And thats it!
For another, more extreme, example see Willi Egger’s My Way on drawing type cases (wooden cases with boxes for storing letter types) used in hand typesetting.
Edit: In a follow-up post, Will Robertson said that he does not like the verbose syntax of ConTeXt tables. Neither do I. As a matter of fact, ConTeXt has multiple table implementations. The oldest table macros, \starttable ... \stoptable
were just a wrapper around the TaBlE macros by Michael Wichura. The syntax of this macro is:
\starttable
\NC .... \NC .... \NC .... \NC \NR
\NC .... \NC .... \NC .... \NC \NR
\NC .... \NC .... \NC .... \NC \NR
\stoptable
But this mechanism is not as powerful as natural tables (that is what the mechanism that I posted is called). There is, however, a wrapper around natural tables that uses the syntax of the old table macros but provides most of the functionality of natural tables:
\startTABLE
\NC .... \NC .... \NC .... \NC \NR
\NC .... \NC .... \NC .... \NC \NR
\NC .... \NC .... \NC .... \NC \NR
\stopTABLE
This is meant for simple tables. Therefore, the \NC
macro does not accept optional arguments. As a result, we cannot use this simpler interface to get the above result. Unless, of course, we cheat. Note the definition of \TC
(tablular cell) below and the deliberate use of \1
and \9
to make the code appear less verbose 🙂
\setupTABLE[each][each][frame=on, rulethickness=3bp, rulecolor=lightred]
\def\TC{\eTD \dobTD}
\def\1{\externalfigure[cow][width=2cm, height=1.5cm]}
\def\9{\externalfigure[cow][width=4cm, height=3cm]}
\starttext
\startTABLE
\NC \1 \NC \1 \NC \1 \NC \1 \NC \1 \NC \1 \NC \NR
\NC \1 \NC \1 \NC \1 \NC \1 \NC \1 \NC \1 \NC \NR
\NC \1 \NC \1 \TC[nc=2,nr=2] \9 \NC \1 \NC \1 \NC \NR
\NC \1 \NC \1 \NC \1 \NC \1 \NC \NR
\NC \1 \NC \1 \NC \1 \NC \1 \NC \1 \NC \1 \NC \NR
\NC \1 \NC \1 \NC \1 \NC \1 \NC \1 \NC \1 \NC \NR
\stopTABLE
\stoptext
I’ve written a quick method to do this in LaTeX here. Not as elegant as the ConTeXt way, but not *too* bad either (IMO).
Dammit; here: http://latex-alive.tumblr.com/post/4181257183/non-textual-tabular-requirements-i-once-wrote-a
(sorry for the ridiculous URLs. Tumblr is a bit weird.)
I agree that the ConTeXt syntax is verbose. In fact, ConTeXt syntax is almost always more verbose that LaTeX syntax. That is part of the reason why ConTeXt is able to provide more control. For example, LaTeX tables are just a wrapper around
\halign
that provide an easy way of specifying column formatting, but do not do anything sophisticated in the body of table (just map\\
to\cr
and provide a few macros for horizontal lines. In ConTeXt, each cell is a frame, and the\bTD ... \eTD
or\NC ... \NR
macros can provide hooks into the underlying frame (keep count of the current row and column number, among other things). In principle that can also be done by making&
active and mapping it to a macro, but that is more trouble than it is worth.And just for fun, I can use a slightly less verbose syntax in ConTeXt (by defining my own macros, so that is cheating)
Your new example looks a lot better to me! I don’t think it’s “cheating” to invent ad hoc markup for things like this; it makes the document code clearer to read.
Perhaps in another post, could elaborate on what a “frame” is in ConteXt? If it’s just a box, how is it possible to align contents over multiple frames? Can verbatim material appear inside? Does the table require trial typesetting before it knows how large everything is and before it can align its contents? Or is \halign more flexible than the LaTeX wrapper interface to it? (You’ll have to forgive my ignorance here.)
Don’t feel obliged to answer any of these questions… I’m mostly just thinking rhetorically.
Frame is a box. You can think of framed as \fbox or minipage on steroids (you can specify width, height, frame, offset, margin, alignment, rotation, background image, background color, foreground color, foreground style, frame color, frame thickness, and a few other things). See http://wiki.contextgarden.net/Framed for some examples. I will try to explain frame sometime in the future (more likely in tugboat rather than on the blog).
I had never tried verbatim inside framed before; I just tried it, and it works!
Table does to trial typesetting to determine the width and heights.
I don’t think that \halign is any more flexible than the LaTeX wrapper. The biggest difficulty with LaTeX tables is that you cannot specify the cell height. The arraystretch trick that you use is fine if you want all cells to be of the same height. But what if I want a particular row to be of a different height. I will have to use \parbox or something similar. The other problem is that multirow/multicolumn is not very convenient.
Just look at the table in Willi’s My Way and try to reproduce that in LaTeX. Or the difficulty that the OP had in creating the table in http://tex.stackexchange.com/q/11937/323
Pingback: Images for documentation examples « Random Determinism