[Tex/LaTex] ConTeXt center tabular

contexthorizontal alignmenttables

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?

Best Answer

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

centered tabulation

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.

Related Question