# ConTeXt center tabular

In ConTeXt, a tabular environment evidently does not behave a centered context. e.g.:

\startalignment[center]
\starttabular
\NC item one \NC item two \NC\NR
\NC item three \NC item four \NC\NR
\stoptabular
\stopalignment


will still result in the table being up against the left side of the page. One answer here advises using \midaligned {} around tables to center them, but this technique seems to throw an error when applied to tabulars. What's the correct way to center a tabular block?

-

The low-level \vbox wrapping aside, there are two way to achieve centered tables relying on the user interface only: Floats and the frame parameter. Floats are more powerful but even with the abundance of placement options they might turn out to behave erratically. So the frame parameter that comes with tabulation-style tables might be the preferred choice in some situations.

%%% This is how you get a “tabular” environment in Context.
\definetabulation [tabular]
\setuptabulation  [tabular] [
format={|r|i{1em}l|},
rulethickness=2pt,
]

%%% Used in solution 2. Note the *align* key.
\defineframedcontent [tabularframe] [frame=off, align=middle]

%%% The table goes into a buffer for later use.
\startbuffer [demotable]
\starttabular
\HL
\NC item one   \NC item two  \NC\NR
\NC item three \NC item four \NC\NR
\LL
\stoptabular
\stopbuffer

\starttext
\input knuth
%%% First solution: Floats.
%%% Use the “here” key to set the float location. Try “force” if it
%%% doesn’t behave.
\placetable[here]{Centered Table Floats}{\getbuffer[demotable]}

%%% Second solution: Frame.
%%% The second solution is even easier: As tabulations respect a
%%% (undocumented?) *frame* parameter, just hook your favorite
%%% *framedcontent* macro in there.
\setuptabulation [tabular] [frame=tabularframe]
\startalignment [middle]
\input ward
\getbuffer[demotable]
\input dawkins
\stopalignment

\stoptext


EDIT As Marco pointed out, the framed version will suppress page breaks. In case your tabulations get too long, you will have to resort to the first version (float, with the split option). Or you can just create a narrower environment that centers the table according to its width. In below listing this is done inside the macro \centertabulation which takes the table as an argument.

\newdimen\current_tabulation_offset

\def\test_hsize#1{
\setbox0\vbox{#1}%
\current_tabulation_offset\dimexpr(\hsize-\wd0)/2
}

\definenarrower [tabulate_narrower]
\setupnarrower  [tabulate_narrower] [
middle=\current_tabulation_offset,
]
\def\centertabulation#1{
\test_hsize{#1}%
\starttabulate_narrower
#1%
\stoptabulate_narrower
}

\protect

\starttext

\startalignment [middle]
\input ward
\centertabulation{\getbuffer[demotable]}
\input ward
\stopalignment

\stoptext


Beware that this approach will misalign all horizontal rules in the table.

-
The frame prevents the tabular from being broken across pages. – Marco May 5 '12 at 14:47
I’d prefer floats with long tables. But I added an alternative that avoids floats anyways. – Philipp Gesang May 5 '12 at 16:58
It is better to use here,force to ensure that the floats don't float. – Aditya May 6 '12 at 1:06

Not sure if this is the canonical way to force centering, but the following should work

\startalignment[middle]
\dontleavehmode
\vbox{%
\starttable[|l|l|]
\NC item one \NC item two \NC\NR
\NC item three \NC item four \NC\NR
\stoptable
}
\stopalignment


The \dontleavehmode command is often used with \startalignment, see e.g. Context help on Command/startalignment. The \vbox trick is something I found on Context mailing.

-