% language=us runpath=texruns:manuals/xtables

% author    : Hans Hagen
% copyright : ConTeXt Development Team
% license   : Creative Commons Attribution ShareAlike 4.0 International
% reference : pragma-ade.nl | contextgarden.net | texlive (related) distributions
% origin    : the ConTeXt distribution
%
% comment   : Because this manual is distributed with TeX distributions it comes with a rather
%             liberal license. We try to adapt these documents to upgrades in the (sub)systems
%             that they describe. Using parts of the content otherwise can therefore conflict
%             with existing functionality and we cannot be held responsible for that. Many of
%             the manuals contain characteristic graphics and personal notes or examples that
%             make no sense when used out-of-context.
%
% comment   : Some chapters might have been published in TugBoat, the NTG Maps, the ConTeXt
%             Group journal or otherwise. Thanks to the editors for corrections. Also thanks
%             to users for testing, feedback and corrections.

\usemodule[art-01,abr-02]

\definecolor[red]    [darkred]
\definecolor[green]  [darkgreen]
\definecolor[blue]   [darkblue]
\definecolor[yellow] [darkyellow]
\definecolor[magenta][darkmagenta]
\definecolor[cyan]   [darkcyan]

\setupexternalfigures
  [location={local,default}]

\setupbodyfont
  [10pt]

\setuptyping
  [color=darkyellow]

\setuptype
  [color=darkcyan]

% \setupnumbering
%   [alternative=doublesided]

\setuphead
  [section]
  [color=darkmagenta]

\setupinteraction
  [hidden]

\startdocument
  [metadata:author=Hans Hagen,
   metadata:title=Extreme Tables,
   author=Hans Hagen,
   affiliation=PRAGMA ADE,
   location=Hasselt NL,
   title=Extreme Tables,
   extra=ConTeXt MkIV,
   support=www.contextgarden.net,
   website=www.pragma-ade.nl]

\startMPpage

    StartPage ;
        fill Page enlarged 2mm withcolor magenta/4 ;
        pickup pencircle scaled 2mm ;
        numeric n ; n := bbheight Page ;
        forever :
            n := n / 1.5 ;
            draw bottomboundary Page shifted (0, n) withcolor 2yellow/3 withtransparency (1,0.5) ;
            draw topboundary    Page shifted (0,-n) withcolor 2yellow/3 withtransparency (1,0.5) ;
            exitif n < 2cm ;
        endfor ;
        numeric n ; n := bbheight Page ;
        forever :
            n := n / 1.5 ;
            draw leftboundary  Page shifted ( n,0) withcolor 2cyan/3 withtransparency (1,0.5) ;
            draw rightboundary Page shifted (-n,0) withcolor 2cyan/3 withtransparency (1,0.5) ;
            exitif n < 2cm ;
        endfor ;
        picture p, q, r ;
        p := textext("\ssbf\WORD{\documentvariable{title}}") xsized (bbheight Page - 2cm) rotated 90 ;
        q := textext("\ssbf\WORD{\documentvariable{author}}") ysized 1cm ;
        r := textext("\ssbf\WORD{\documentvariable{extra}}") xsized bbwidth q ;
        draw anchored.rt (p, center rightboundary  Page shifted (-1cm,0cm)) withcolor white ;
        draw anchored.bot(q, center bottomboundary Page shifted ( 1cm,4.4cm)) withcolor white ;
        draw anchored.bot(r, center bottomboundary Page shifted ( 1cm,2.8cm)) withcolor white ;
    StopPage ;

\stopMPpage

% \page[empty] \setuppagenumber[start=1]

\startsubject[title={Contents}]

\placelist[section][criterium=all,interaction=all]

\stopsubject

\startsection[title={Introduction}]

This is a short introduction to yet another table mechanism built in \CONTEXT. It
is a variant of the so called natural tables but it has a different
configuration. Also, the implementation is completely different. The reason for
writing it is that in one of our projects we had to write styles for documents
that had tables spanning 30 or more pages and apart from memory constraints this
is quite a challenge for the other mechanisms, if only because splitting them
into successive floats is not possible due to limitations of \TEX. The extreme
table mechanism can handle pretty large tables and split them too. As each cell
is basically a \type {\framed} and as we need to do two passes over the table,
this mechanism is not the fastest but it is some two times faster than the
natural tables mechanism, and in most cases can be used instead.

\stopsection

\startsection[title={The structure}]

The structure of the tables is summarized here. There can be the usual head, body
and foot specifications and we also support the optional header in following
pages.

\starttyping
\definextable [tag] | [tag][parent]
\setupxtable [settings] | [tag][settings]

\startxtable[tag|settings]
  \startxtablehead|next|body|foot[tag|settings]
    \startxrowgroup[tag|settings]
      \startxrow[settings]
        \startxcellgroup[tag|settings]
          \startxcell[settings] ... \stopxcell
        \stopxcellgroup
      \stopxrow
    \stopxrowgroup
  \stopxtablehead|next|body|foot
\stopxtable
\stoptyping

Contrary to what you might expect, the definition command defines a new set of
command. You don't need to use this in order to set up a new settings
environment. Settings and definitions can inherit so you can build a chain of
parent|-|child settings. The grouping is nothing more than a switch to a new set
of settings.

\stopsection

\startsection[title={Direct control}]

A simple table with just frames is defined as follows:

\startbuffer
\startxtable
  \startxrow
    \startxcell one   \stopxcell
    \startxcell two   \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha \stopxcell
    \startxcell beta  \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer

\startlinecorrection[blank] \getbuffer \stoplinecorrection

You can pass parameters for tuning the table:

\startbuffer
\startxtable[offset=1cm]
  \startxrow
    \startxcell one   \stopxcell
    \startxcell two   \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha \stopxcell
    \startxcell beta  \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer

\startlinecorrection[blank] \getbuffer \stoplinecorrection

You can (for as much as they make sense) use the same settings as the \type
{\framed} command, as long as you keep in mind that messing with the frame
related offsets can have side effects.

\stopsection

\startsection[title={Sets of settings}]

Instead of directly passing settings you can use a predefined set. Of course you
can also combine these methods.

\startbuffer
\definextable
  [myxtable]

\definextable
  [myxtable:important]
  [myxtable]

\setupxtable
  [myxtable]
  [width=4cm,
   foregroundcolor=red]

\setupxtable
  [myxtable:important]
  [background=color,
   backgroundcolor=red,
   foregroundcolor=white]
\stopbuffer

\typebuffer \getbuffer

We can use these settings in table. Although it is not really needed to define a
set beforehand (i.e.\ you can just use the setup command) it is cleaner and more
efficient too.

\startbuffer
\startxtable[myxtable]
  \startxrow[foregroundcolor=green]
    \startxcell one \stopxcell
    \startxcell two \stopxcell
    \startxcellgroup[foregroundcolor=blue]
      \startxcell tree  \stopxcell
      \startxcell four  \stopxcell
    \stopxcellgroup
  \stopxrow
  \startxrow
    \startxcell alpha \stopxcell
    \startxcell beta  \stopxcell
    \startxcellgroup[myxtable:important]
      \startxcell gamma \stopxcell
      \startxcell delta \stopxcell
    \stopxcellgroup
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer

\startlinecorrection[blank] \getbuffer \stoplinecorrection

The overhead of (chained) settings is quite acceptable and it helps to keep the
source of the table uncluttered from specific settings.

\stopsection

\startsection[title={Defining}]

If needed you can define your own encapsulating commands. The following example
demonstrates this:

\startbuffer
\definextable[mytable]
\stopbuffer

\getbuffer \typebuffer

We now can use the \type{mytable} wrapper:

\startbuffer
\startmytable[height=4cm,width=8cm,align={middle,lohi}]
  \startxrow
    \startxcell test \stopxcell
  \stopxrow
\stopmytable
\stopbuffer

\typebuffer

\startlinecorrection[blank] \getbuffer \stoplinecorrection

One drawback of using buffers is that they don't play well in macro definitions.
In that case you need to use the following wrapper:

\startbuffer
\starttexdefinition MyTable #1#2#3#4
  \startembeddedxtable
    \startxrow
      \startxcell #1 \stopxcell
      \startxcell #2 \stopxcell
    \stopxrow
    \startxrow
      \startxcell #3 \stopxcell
      \startxcell #4 \stopxcell
    \stopxrow
  \stopembeddedxtable
\stoptexdefinition
\stopbuffer

\typebuffer \getbuffer

This macro is used as any other macro with arguments:

\startbuffer
\MyTable{one}{two}{three}{four}
\stopbuffer

\typebuffer

\startlinecorrection[blank] \getbuffer \stoplinecorrection

\stopsection

\startsection[title={Stretching}]

If you don't give the width of a cell, the widest natural size will be taken.
Otherwise the given width applies to the whole column.

\startbuffer
\startxtable
  \startxrow
    \startxcell[width=1cm] one  \stopxcell
    \startxcell[width=2cm] two  \stopxcell
    \startxcell[width=3cm] tree \stopxcell
    \startxcell[width=4cm] four \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha \stopxcell
    \startxcell beta  \stopxcell
    \startxcell gamma \stopxcell
    \startxcell delta \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer

\startlinecorrection[blank] \getbuffer \stoplinecorrection

You can let the cells stretch so that the whole width of the text area is taken.

\startbuffer[one]
\startxtable[option=stretch]
  \startxrow
    \startxcell[width=1cm] one  \stopxcell
    \startxcell[width=2cm] two  \stopxcell
    \startxcell[width=3cm] tree \stopxcell
    \startxcell[width=4cm] four \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha \stopxcell
    \startxcell beta  \stopxcell
    \startxcell gamma \stopxcell
    \startxcell delta \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer[one]

The available left over space is equally distributed among the cells.

\startlinecorrection[blank] \getbuffer[one] \stoplinecorrection

\startbuffer[two]
\startxtable[option={stretch,width}]
  \startxrow
    \startxcell[width=1cm] one  \stopxcell
    \startxcell[width=2cm] two  \stopxcell
    \startxcell[width=3cm] tree \stopxcell
    \startxcell[width=4cm] four \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha \stopxcell
    \startxcell beta  \stopxcell
    \startxcell gamma \stopxcell
    \startxcell delta \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

An alternative is to distribute the space proportionally:

\typebuffer[two]

\startlinecorrection[blank] \getbuffer[two] \stoplinecorrection

Just to stress the difference we show both alongside now:

\startlinecorrection[blank]
    \getbuffer[one]
    \blank
    \getbuffer[two]
\stoplinecorrection

You can specify the width of a cell with each cell but need to keep into mind
that that value is then used for the whole column:

\startbuffer
\startxtable
  \startxrow
    \startxcell[width=1em] one  \stopxcell
    \startxcell[width=2em] two  \stopxcell
    \startxcell[width=3em] tree \stopxcell
    \startxcell[width=4em] four \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha \stopxcell
    \startxcell beta  \stopxcell
    \startxcell gamma \stopxcell
    \startxcell delta \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer

\startlinecorrection[blank] \getbuffer \stoplinecorrection

You can enforce that larger columns win via the \type {option} parameter:

\startbuffer
\startxtable[option=max]
  \startxrow
    \startxcell[width=1em] one  \stopxcell
    \startxcell[width=2em] two  \stopxcell
    \startxcell[width=3em] tree \stopxcell
    \startxcell[width=4em] four \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha \stopxcell
    \startxcell beta  \stopxcell
    \startxcell gamma \stopxcell
    \startxcell delta \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer

\startlinecorrection[blank] \getbuffer \stoplinecorrection

\stopsection

\startsection[title={Spacing}]

It is possible to separate the cells by horizontal and/or vertical space. As an
example we create a setup.

\startbuffer
\setupxtable
  [myztable]
  [option=stretch,
   foregroundcolor=blue,
   columndistance=10pt,
   leftmargindistance=20pt,
   rightmargindistance=30pt]
\stopbuffer

\typebuffer \getbuffer

You can use the \type {textwidth} parameter to set a specific maximum width. We
now apply the previous settings to an extreme table:

\startbuffer
\startxtable[myztable]
  \startxrow
    \startxcell[width=1cm] one              \stopxcell
    \startxcell[width=2cm,distance=5pt] two \stopxcell
    \startxcell[width=3cm] tree             \stopxcell
    \startxcell[width=4cm] four             \stopxcell
  \stopxrow
  \startxrow
    \startxcell[width=1cm] alpha \stopxcell
    \startxcell[width=2cm] beta  \stopxcell
    \startxcell[width=3cm] gamma \stopxcell
    \startxcell[width=4cm] delta \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer

As you can see here, we can still locally overload the settings but keep in mind
that these apply to the whole column then, not to the specific cell.

\startlinecorrection[blank] \getbuffer \stoplinecorrection

Vertical spacing is (currently) setup differently, i.e.\ as an argument to the
\type {\blank} command.

\startbuffer
\startxtable[spaceinbetween=medium]
  \startxrow
    \startxcell one  \stopxcell
    \startxcell two  \stopxcell
    \startxcell tree \stopxcell
    \startxcell four \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha \stopxcell
    \startxcell beta  \stopxcell
    \startxcell gamma \stopxcell
    \startxcell delta \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer

Specifying spacing this way improves consistency with the rest of the document
spacing.

\startlinecorrection[blank] \getbuffer \stoplinecorrection

\stopsection

\startsection[title={Spanning}]

Of course we can span cells horizontally as well as vertically. Future versions
might provide more advanced options but the basics work okay.

\startbuffer
\startxtable
  \startxrow
    \startxcell one \stopxcell
    \startxcell[nx=2] two + three \stopxcell
    \startxcell four \stopxcell
    \startxcell five \stopxcell
  \stopxrow
  \startxrow
    \startxcell[nx=3] alpha + beta + gamma \stopxcell
    \startxcell[nx=2] delta + epsilon \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer

This spans a few cells horizontally:

\startlinecorrection[blank] \getbuffer \stoplinecorrection

The next example gives a span in two directions:

\startbuffer
\startxtable
  \startxrow
    \startxcell alpha 1 \stopxcell
    \startxcell beta  1 \stopxcell
    \startxcell gamma 1 \stopxcell
    \startxcell delta 1 \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha 2 \stopxcell
    \startxcell[nx=2,ny=2] whatever \stopxcell
    \startxcell delta 2 \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha 3 \stopxcell
    \startxcell delta 3 \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha 4 \stopxcell
    \startxcell beta  4 \stopxcell
    \startxcell gamma 4 \stopxcell
    \startxcell delta 4 \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer

Of course, spanning is always a compromise but the best fit found by this
mechanism takes natural width, given width and available space into account.

\startlinecorrection[blank] \getbuffer \stoplinecorrection

\stopsection

\startsection[title={Partitioning}]

You can partition a table as follows:

\startbuffer
\startxtable
  \startxtablehead
    \startxrow
      \startxcell head one  \stopxcell
      \startxcell head two  \stopxcell
      \startxcell head tree \stopxcell
      \startxcell head four \stopxcell
    \stopxrow
  \stopxtablehead
  \startxtablenext
    \startxrow
      \startxcell next one  \stopxcell
      \startxcell next two  \stopxcell
      \startxcell next tree \stopxcell
      \startxcell next four \stopxcell
    \stopxrow
  \stopxtablenext
  \startxtablebody
    \startxrow
      \startxcell body one  \stopxcell
      \startxcell body two  \stopxcell
      \startxcell body tree \stopxcell
      \startxcell body four \stopxcell
    \stopxrow
  \stopxtablebody
  \startxtablefoot
    \startxrow
      \startxcell foot one  \stopxcell
      \startxcell foot two  \stopxcell
      \startxcell foot tree \stopxcell
      \startxcell foot four \stopxcell
    \stopxrow
  \stopxtablefoot
\stopxtable
\stopbuffer

\typebuffer

There can be multiple such partitions and they are collected in head, next, body
and foot groups. Normally the header ends up at the beginning and the footer at
the end. When a table is split, the first page gets the header and the following
pages the next one.

You can let headers and footers be repeated by setting the \type {header}
and|/|or \type {footer} parameters to \type {repeat}.

\starttyping
\setupxtable
  [split=yes,
   header=repeat,
   footer=repeat]
\stoptyping

The table can be flushed in the running text but also in successive
floats. Given that the table is in a buffer:

\starttyping
\placetable[here,split]{A big table.}{\getbuffer}
\stoptyping

When you specify \type {split} as \type {yes} the caption is taken into account
when calculating the available space.

There are actually three different split methods. The \type {yes} option works in
text mode as well as in floats, but in text mode no headers and footers get
repeated. If you want that feature in a text flush you have to set \type {split}
to \type {repeat} as well.

You can keep rows together by passing a \type {samepage} directive. This
parameter can get the values \type {before}, \type {after} and \type {both}.

\starttyping
\startxtable[split=yes]
  \startxrow                \startxcell \tttf      .01. \stopxcell \stopxrow
  \startxrow                \startxcell \tttf      .... \stopxcell \stopxrow
  \startxrow                \startxcell \tttf \red .21. \stopxcell \stopxrow
  \startxrow[samepage=both] \startxcell \tttf \red .22. \stopxcell \stopxrow
  \startxrow[samepage=both] \startxcell \tttf \red .23. \stopxcell \stopxrow
  \startxrow                \startxcell \tttf      .... \stopxcell \stopxrow
  \startxrow                \startxcell \tttf      .99. \stopxcell \stopxrow
\stopxtable
\stoptyping

\stopsection

\startsection[title={Options}]

On the average a table will come out okay but you need to keep in mind that when
(complex) spans are used the results can be less that optimal. However, as
normally one pays attention to creating tables, the amount of control provided
often makes it possible to get what you want.

In the following situations, the first cell width is determined by the span. It
is possible to make a more clever analyzer but we need to keep in mind that in
the same column there can be entries that span a different amount of columns. Not
only would that be inefficient but it would also be rather unpredictable unless
you know exactly what happens deep down. The following two examples demonstrate
default behaviour.

\startbuffer
\startxtable
  \startxrow
    \startxcell[nx=3]
        1/2/3
    \stopxcell
  \stopxrow
  \startxrow
    \startxcell 1 \stopxcell
    \startxcell 2 \stopxcell
    \startxcell 3 \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\startxtable
  \startxrow
    \startxcell[nx=3]
        1 / 2 / 3
    \stopxcell
  \stopxrow
  \startxrow
    \startxcell 1 \stopxcell
    \startxcell 2 \stopxcell
    \startxcell 3 \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

In practice you will set the width of the columns, as in:

\startbuffer
\startxtable
  \startxrow
    \startxcell[nx=3]
        1/2/3
    \stopxcell
  \stopxrow
  \startxrow
    \startxcell[width=\dimexpr\textwidth/3] 1 \stopxcell
    \startxcell[width=\dimexpr\textwidth/3] 2 \stopxcell
    \startxcell[width=\dimexpr\textwidth/3] 3 \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

But, if you want you can control the enforced width by setting an option:

\startbuffer
\startxtable
  \startxrow
    \startxcell[nx=3,option=tight]
        1/2/3
    \stopxcell
  \stopxrow
  \startxrow
    \startxcell 1 \stopxcell
    \startxcell 2 \stopxcell
    \startxcell 3 \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\startxtable
  \startxrow
    \startxcell[nx=3,option=tight]
        1 / 2 / 3
    \stopxcell
  \stopxrow
  \startxrow
    \startxcell 1 \stopxcell
    \startxcell 2 \stopxcell
    \startxcell 3 \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

There is also a global setting:

\startbuffer
\startxtable[option=tight]
  \startxrow
    \startxcell[nx=3]
      1/2/3
    \stopxcell
  \stopxrow
  \startxrow
    \startxcell 1 \stopxcell
    \startxcell 2 \stopxcell
    \startxcell 3 \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\stopsection

\startsection[title={Nesting}]

Extreme tables can be nested but you need to keep an eye on inheritance here as
the inner table uses the settings from the encapsulating cell. The widths and
heights of the inner table default to \type {fit}. We could cook up a more
complex nesting model but this one is easy to follow.

\startbuffer
\startxtable
  \startxrow
    \startxcell[offset=0pt]
      \startxtable[background=color,backgroundcolor=green,
            foregroundcolor=white,offset=1ex]
        \startxrow
          \startxcell[width=1cm] one \stopxcell
          \startxcell[width=2cm] two \stopxcell
        \stopxrow
        \startxrow
          \startxcell[width=3cm] alpha \stopxcell
          \startxcell[width=4cm] beta  \stopxcell
        \stopxrow
      \stopxtable
    \stopxcell
    \startxcell two   \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha \stopxcell
    \startxcell
      \startxtable[background=color,backgroundcolor=red,
            foregroundcolor=white]
        \startxrow
          \startxcell one \stopxcell
          \startxcell two \stopxcell
        \stopxrow
        \startxrow
          \startxcell alpha \stopxcell
          \startxcell beta  \stopxcell
        \stopxrow
      \stopxtable
    \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer

Here we just manipulate the offset a bit.

\startlinecorrection[blank] \getbuffer \stoplinecorrection

\stopsection

\startsection[title={Buffers}]

When you don't want to clutter your document source too much buffers can be if
help:

\startbuffer
\startbuffer[test]
\startxtable
  \startxrow
    \startxcell[width=1cm] one \stopxcell
    \startxcell[width=2cm] two \stopxcell
  \stopxrow
  \startxrow
    \startxcell alpha \stopxcell
    \startxcell beta  \stopxcell
  \stopxrow
\stopxtable
\stopbuffer
\stopbuffer

\typebuffer \getbuffer

One way of getting this table typeset is to say:

\starttyping
\getbuffer[test]
\stoptyping

Normally this is quite okay. However, internally extreme tables become also
buffers. If you don't like the overhead of this double buffering you can use the
following command:

\starttyping
\processxtablebuffer[test]
\stoptyping

This can save you some memory and runtime, but don't expect miracles. Also, this
way of processing does not support nested tables (unless \type {{}} is used).

\stopsection

\startsection[title={XML}]

The following example demonstrates that we can use this mechanism in \XML\ too.
The example was provided by Thomas Schmitz. First we show how a table looks like
in \XML:

\startbuffer[test]
<table>
  <tablerow>
      <tablecell>
        One
      </tablecell>
      <tablecell>
        Two
      </tablecell>
  </tablerow>
  <tablerow>
    <tablecell>
      <b>Three</b>
    </tablecell>
    <tablecell>
      Four
    </tablecell>
  </tablerow>
</table>
\stopbuffer

\typebuffer[test]

We need to map these elements to setups:

\startbuffer
\startxmlsetups xml:testsetups
    \xmlsetsetup{main}{b|table|tablerow|tablecell}{xml:*}
\stopxmlsetups

\xmlregistersetup{xml:testsetups}
\stopbuffer

\typebuffer \getbuffer

The setups themselves are rather simple as we don't capture any attributes.

\startbuffer
\startxmlsetups xml:b
  \bold{\xmlflush{#1}}
\stopxmlsetups

\startxmlsetups xml:table
  \startembeddedxtable
    \xmlflush{#1}
  \stopembeddedxtable
\stopxmlsetups

\startxmlsetups xml:tablerow
  \startxrow
    \xmlflush{#1}
  \stopxrow
\stopxmlsetups

\startxmlsetups xml:tablecell
  \startxcell
    \xmlflush{#1}
  \stopxcell
\stopxmlsetups
\stopbuffer

\typebuffer \getbuffer

We now process the example. Of course it will also work for files.

\startbuffer
\xmlprocessbuffer{main}{test}{}
\stopbuffer

\typebuffer

The result is:

\startlinecorrection[blank] \getbuffer \stoplinecorrection

\stopsection

\startsection[title={Natural tables}]

For the impatient a small additional module is provided that remaps the natural
table commands onto extreme tables:

\startbuffer
\usemodule[ntb-to-xtb]
\stopbuffer

\typebuffer \getbuffer

After that:

\startbuffer
\bTABLE
  \bTR
    \bTD[background=color,backgroundcolor=red] one \eTD
    \bTD[width=2cm] two \eTD
  \eTR
  \bTR
    \bTD[width=5cm] alpha \eTD
    \bTD[background=color,backgroundcolor=yellow] beta \eTD
  \eTR
\eTABLE
\stopbuffer

\typebuffer

Will come out as:

\startlinecorrection[blank]
\getbuffer
\stoplinecorrection

You can restore and remap the commands with the following helpers:

\starttyping
\restoreTABLEfromxtable
\mapTABLEtoxtable
\stoptyping

Of course not all functionality of the natural tables maps onto similar
functionality of extreme tables, but on the average the result will look rather
similar.

\stopsection

\startsection[title={Alignment}]

\enabletrackers[typesetters.characteralign]

There is limited support for aligning numbers in columns. When you flush right
and have a fixed number of digits it's not a problem, but otherwise it might come
in handy. In any case, you might want to use the following as part of your style:

\starttyping
\addfeature[tabularnumbers]
\stoptyping

\start \addfeature[tabularnumbers]

The basic alignment mechanism can be demonstrated with the following examples:

\startbuffer
\startcharacteralign[,] % or [character={,}]
    \checkcharacteralign{123.456,78} \par
    \checkcharacteralign    {456}    \par
    \checkcharacteralign {23.456}    \par
    \checkcharacteralign     {78,9}  \par
    \checkcharacteralign     {78}    \par
\stopcharacteralign
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\startcharacteralign[leftsample=123.456,rightsample=00,character={,}]
    \checkcharacteralign{123.456,78} \par
    \checkcharacteralign    {456}    \par
    \checkcharacteralign {23.456}    \par
    \checkcharacteralign     {78,9}  \par
    \checkcharacteralign     {78}    \par
\stopcharacteralign
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\startcharacteralign[leftwidth=100pt,rightwidth=30pt]
    \checkcharacteralign{123.456,78} \par
    \checkcharacteralign    {456}    \par
    \checkcharacteralign {23.456}    \par
    \checkcharacteralign     {78,9}  \par
    \checkcharacteralign     {78}    \par
\stopcharacteralign
\stopbuffer

\typebuffer \getbuffer

Samples win over width settings. When no sample or width is given a two pass
analyzer kicks in. This is not the case in the following examples.

\startbuffer
\startxtable
    [align={flushright,lohi},
     aligncharacter=yes,
     alignmentleftsample=100,
     alignmentrightsample=00,
     alignmentcharacter={.}]
  \startxrow \startxcell 1     \stopxcell \stopxrow
  \startxrow \startxcell 1.1   \stopxcell \stopxrow
  \startxrow \startxcell 11.11 \stopxcell \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\startxtable
    [align={flushright,lohi},
     aligncharacter=yes,
     alignmentleftsample=000.000,
     alignmentrightsample=00,
     alignmentcharacter={,}]
  \startxrow \startxcell 123.456,78 x \stopxcell \stopxrow
  \startxrow \startxcell     456    x \stopxcell \stopxrow
  \startxrow \startxcell 23.456     x \stopxcell \stopxrow
  \startxrow \startxcell     78,9   x \stopxcell \stopxrow
  \startxrow \startxcell     78     x \stopxcell \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\startxtable[align={flushright,lohi}]
  \startxrow
    \startxcell
        [aligncharacter=yes,
         alignmentcharacter={,},
         alignmentleftsample=000.000,
         alignmentrightsample=00]
        123.456,78
    \stopxcell
  \stopxrow
  \startxrow
    \startxcell
        [aligncharacter=yes]
        456
    \stopxcell
  \stopxrow
  \startxrow
    \startxcell
        [aligncharacter=yes]
        23.456
    \stopxcell
  \stopxrow
  \startxrow
    \startxcell
        [aligncharacter=yes]
        78,9
    \stopxcell
  \stopxrow
  \startxrow
    \startxcell
        [aligncharacter=yes]
        78
    \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\setupxtable
  [aligned]
  [aligncharacter=yes,
   alignmentleftsample=000.000,
   alignmentrightsample=00,
   alignmentcharacter={,}]

\startxtable[align={flushright,lohi}]
  \startxrow \startxcell[aligned] 123.456,78 \stopxcell \stopxrow
  \startxrow \startxcell[aligned]     456    \stopxcell \stopxrow
  \startxrow \startxcell[aligned] 23.456     \stopxcell \stopxrow
  \startxrow \startxcell[aligned]     78,9   \stopxcell \stopxrow
  \startxrow \startxcell[aligned]     78     \stopxcell \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\stop

\disabletrackers[typesetters.characteralign]

\stopsection

\startsection[title={Depth}]

Take the following example. Here we have some text that, when typeset narrow,
will have a last line with no (or, depending on the font, hardly) depth.

\startbuffer
\startxtable[frame=on]

    \startxrow
        \startxcell[width=3cm]
            here filled with some words to force a rather long line
        \stopxcell
    \stopxrow

    \startxrow
        \startxcell
            here filled with some words to force a rather long line
        \stopxcell
    \stopxrow

    \startxrow
        \startxcell
            here filled with some words to force a rather long line

        \stopxcell
    \stopxrow

\stopxtable
\stopbuffer

\typebuffer

The problem is that \TEX\ doesn't add depth that that last line and adding it
automatically can be done in grid mode but one doesn't always want that. Some mechanisms
add so called struts automatically. As the table cells are framed boxes indeed that
happens here, unless you add an empty line (as in the last row). When you embed

\startlinecorrection[blank] {\showstruts \showboxes \getbuffer} \stoplinecorrection

\startbuffer
\startxtable[frame=on]

    \startxrow
        \startxcell[width=3cm]
            \startitemize[packed]
                \startitem
                    here filled with some words to force a rather long line
                \stopitem
            \stopitemize
        \stopxcell
    \stopxrow

    \startxrow
        \startxcell
            \startitemize[packed]
                \startitem
                    here filled with some words to force a rather long line
                \stopitem
            \stopitemize
        \stopxcell
    \stopxrow

    \startxrow
        \startxcell
            \startitemize[packed]
                \startitem
                    here filled with some words to force a rather long line

                \stopitem
            \stopitemize
        \stopxcell
    \stopxrow

\stopxtable
\stopbuffer

\typebuffer

Don't count on all mechanisms used inside a cell to provide this but with itemize
you're lucky.

\startlinecorrection[blank] {\showstruts \showboxes \getbuffer} \stoplinecorrection

\stopsection

\startsection[title={Swapping}]

The next two examples demonstrate a feature added for Taco, who wanted to input
vertical instead of horizontal. It's a bit of a hack but it works okay for
simple cases. We assume these settings:

\startbuffer[settings]
\setupxtable[one]  [foregroundcolor=darkred]
\setupxtable[two]  [foregroundcolor=darkgreen]
\setupxtable[three][foregroundcolor=darkblue]
\setupxtable[four] [foregroundcolor=darkorange]
\stopbuffer

\startbuffer[demo-1]
\startxtable[frame=on]
    \startxcolumn[one]
        \startxcell A1 \stopxcell
        \startxcell B1 \stopxcell
        \startxcell C1 \stopxcell
        \startxcell D1 \stopxcell
        \startxcell E1 \stopxcell
    \stopxcolumn
    \startxcolumn[two]
        \startxcell A2 \stopxcell
        \startxcell B2 \stopxcell
        \startxcell C2 \stopxcell
        \startxcell D2 \stopxcell
        \startxcell E2 \stopxcell
    \stopxcolumn
    \startxcolumn[three]
        \startxcell A3 \stopxcell
        \startxcell B3 \stopxcell
        \startxcell C3 \stopxcell
        \startxcell D3 \stopxcell
        \startxcell E3 \stopxcell
    \stopxcolumn
    \startxcolumn[four]
        \startxcell A4 \stopxcell
        \startxcell B4 \stopxcell
        \startxcell C4 \stopxcell
        \startxcell D4 \stopxcell
        \startxcell E4 \stopxcell
    \stopxcolumn
\stopxtable
\stopbuffer

\startbuffer[demo-2]
\startxtable[frame=on]
    \startxcolumn[one]
        \startxcell A \stopxcell
        \startxcell B \stopxcell
        \startxcell C \stopxcell
        \startxcell D \stopxcell
        \startxcell E \stopxcell
    \stopxcolumn
    \startxcolumn[two]
        \startxcell       A  \stopxcell
        \startxcell[ny=2] BC \stopxcell
        \startxcell[ny=2] DE \stopxcell
    \stopxcolumn
    \startxcolumn[three]
        \startxcell       A    \stopxcell
        \startxcell[ny=4] BCDE \stopxcell
    \stopxcolumn
    \startxcolumn[four]
        \startxcell       A \stopxcell
        \startxcell       B \stopxcell
        \startxcell[ny=2] CD \stopxcell
        \startxcell       E  \stopxcell
    \stopxcolumn
\stopxtable
\stopbuffer

\typebuffer[settings]

The first example has no spans:

\typebuffer[demo-1]

while the second one has:

\typebuffer[demo-2]

The results are shown in \in {figure} [fig:swapped].

\startplacefigure[title={Entering columns instead of rows.},reference=fig:swapped]
    \getbuffer[settings]
    \startcombination
        {\getbuffer[demo-1]} {no spans}
        {\getbuffer[demo-2]} {some spans}
    \stopcombination
\stopplacefigure

\stopsection

\startsection[title={Examples}]

On the following pages we show some examples of (experimental) features. For this
we will use the usual quotes from Ward, Tufte and Davis etc.\ that you can find
in the distribution.

\page

\startbuffer
\startxtable[bodyfont=6pt]
    \startxrow
        \startxcell \input ward  \stopxcell
        \startxcell \input tufte \stopxcell
        \startxcell \input davis \stopxcell
    \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\startxtable[bodyfont=6pt,option=width]
    \startxrow
        \startxcell \input ward  \stopxcell
        \startxcell \input tufte \stopxcell
        \startxcell \input davis \stopxcell
    \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\page

\startbuffer
\startxtable[bodyfont=6pt]
    \startxrow
        \startxcell \externalfigure[cow.pdf][width=3cm] \stopxcell
        \startxcell \input tufte \stopxcell
        \startxcell \input davis \stopxcell
    \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\startxtable[bodyfont=6pt,option=width]
    \startxrow
        \startxcell \externalfigure[cow.pdf][width=3cm] \stopxcell
        \startxcell \input tufte \stopxcell
        \startxcell \input davis \stopxcell
    \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\page

\startbuffer
\startxtable[option=stretch]
    \startxrow
        \startxcell bla \stopxcell
        \startxcell bla bla \stopxcell
        \startxcell bla bla bla \stopxcell
    \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\startxtable[option={stretch,width}]
    \startxrow
        \startxcell bla \stopxcell
        \startxcell bla bla \stopxcell
        \startxcell bla bla bla \stopxcell
    \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\page

\startbuffer
\setupxtable[suffix][align=middle,foregroundcolor=red]
\setupxtable[blabla][foregroundstyle=slanted]
\setupxtable[crap]  [foregroundcolor=blue]
\setupxtable[bold]  [crap][foregroundstyle=bold]

\startxtable % [frame=off]
    \startxtablehead
        \startxrow[bold]
            \startxcell[suffix]       head a \stopxcell
            \startxcell[blabla]       head b \stopxcell
            \startxcell               head c \stopxcell
        \stopxrow
    \stopxtablehead
    \startxtablebody
        \startxrow
            \startxcell[suffix][ny=2] cell a 1 \stopxcell
            \startxcell               cell b 1 \stopxcell
            \startxcell               cell c 1 \stopxcell
        \stopxrow
        \startxrow
            \startxcell               cell b 2 \stopxcell
            \startxcell               cell c 2 \stopxcell
        \stopxrow
        \startxrow
            \startxcell[suffix]       cell a 3 \stopxcell
            \startxcell               cell b 3 \stopxcell
            \startxcell               cell c 3 \stopxcell
        \stopxrow
        \startxrow
            \startxcell[suffix]       cell a 4 \stopxcell
            \startxcell               cell b 4 \stopxcell
            \startxcell               cell c 4 \stopxcell
        \stopxrow
        \startxrow
            \startxcell[suffix]       cell a 5 \stopxcell
            \startxcell               cell b 5 \stopxcell
            \startxcell               cell c 5 \stopxcell
        \stopxrow
    \stopxtablebody
\stopxtable
\stopbuffer

\typebuffer \start \getbuffer \stop

\page

\startbuffer
\startxtable[option=stretch]
    \startxrow
        \startxcell[option=fixed] first cell \stopxcell
        \startxcell 101 \stopxcell
        \startxcell 102 \stopxcell
        \startxcell 103 \stopxcell
    \stopxrow
    \startxrow
        \startxcell 2\high{nd} cell \stopxcell
        \startxcell a \stopxcell
        \startxcell b \stopxcell
        \startxcell c \stopxcell
    \stopxrow
\stopxtable
\stopbuffer

\typebuffer \start \getbuffer \stop

\page

\startbuffer[demo]
\startxtable
\startxrow
    \startxcell[demo][nx=4] 1 / 2 / 3 / 4 \stopxcell
\stopxrow
\startxrow
    \startxcell[demo][nx=3] 1 / 2 / 3 \stopxcell
    \startxcell 4 \stopxcell
\stopxrow
\startxrow
    \startxcell 1 \stopxcell
    \startxcell[demo][nx=3] 2 / 3 / 4 \stopxcell
\stopxrow
\startxrow
    \startxcell[demo][nx=2] 1 / 2 \stopxcell
    \startxcell 3 \stopxcell
    \startxcell 4 \stopxcell
\stopxrow
\startxrow
    \startxcell 1 \stopxcell
    \startxcell[demo][nx=2] 2 / 3 \stopxcell
    \startxcell 4 \stopxcell
\stopxrow
\startxrow
    \startxcell 1 \stopxcell
    \startxcell 2 \stopxcell
    \startxcell[demo][nx=2] 3 / 4 \stopxcell
\stopxrow
\startxrow
    \startxcell[demo][nx=2] 1 / 2 \stopxcell
    \startxcell[demo][nx=2] 3 / 4 \stopxcell
\stopxrow
\startxrow
    \startxcell 1 \stopxcell
    \startxcell 2 \stopxcell
    \startxcell 3 \stopxcell
    \startxcell 4 \stopxcell
\stopxrow
\stopxtable
\stopbuffer

\startbuffer[tight]
\setupxtable[demo][option=tight]
\stopbuffer

\startbuffer[normal]
\setupxtable[demo][option=]
\stopbuffer

\typebuffer[demo]

\page

\typebuffer[tight]  \start \getbuffer[tight,demo]  \stop
\typebuffer[normal] \start \getbuffer[normal,demo] \stop

\page

\startbuffer
\startxtable[align={middle,lohi}]
  \startxrow
    \startxcell[ny=3] (1,3) \stopxcell
    \startxcell       (1,1) \stopxcell
    \startxcell       (1,1) \stopxcell
  \stopxrow
  \startxrow
    \startxcell       (1,1) \stopxcell
    \startxcell       (1,1) \stopxcell
  \stopxrow
  \startxrow
    \startxcell[nx=2] (2,1) \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\startxtable[align={middle,lohi}]
  \startxrow
    \startxcell[ny=2] (1,2) \stopxcell
    \startxcell       (1,1) \stopxcell
    \startxcell       (1,1) \stopxcell
  \stopxrow
  \startxrow
    \startxcell       (1,1) \stopxcell
    \startxcell       (1,1) \stopxcell
  \stopxrow
  \startxrow
    \startxcell[nx=2] (2,1) \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\startxtable[align={middle,lohi}]
  \startxrow
    \startxcell[ny=2] (1,2) \stopxcell
    \startxcell       (1,1) \stopxcell
    \startxcell       (1,1) \stopxcell
    \startxcell       (1,1) \stopxcell
  \stopxrow
  \startxrow
    \startxcell[nx=3] (3,1) \stopxcell
  \stopxrow
  \startxrow
    \startxcell[nx=4] (4,1) \stopxcell
  \stopxrow
\stopxtable
\stopbuffer

\typebuffer \getbuffer

\stopsection

\page

% \ruledhbox{\getbuffer[normal,demo]}

\startsection[title={Colofon}]

\starttabulate[|B|p|]
\NC author    \NC \documentvariable{author}, \documentvariable{affiliation}, \documentvariable{location} \NC \NR
\NC version   \NC \currentdate \NC \NR
\NC website   \NC \documentvariable{website} \endash\ \documentvariable{support} \NC \NR
\NC copyright \NC \symbol[cc][cc-by-sa] \NC \NR
\stoptabulate

\stopsection

\stopdocument

