# Creating a table which spans verso and recto pages in ConTeXt?

I am preparing a book which contains information which is divided into three columns. The first column (A) occupies the full width of all verso pages. The second (B) and third (C) column share the recto page, e.g:

    (verso)    (recto)
_______________________
|           |     |     |
|     A     |  B  |  C  |
|           |     |     |
|           |     |     |
|           |     |     |
|           |     |     |
|           |     |     |
|           |     |     |
|           |     |     |
|___________|_____|_____|


With data inside, the rows on the verso page and recto page should line up vertically:

 _______________________
|           |     |     |
|This text  |This |This |
|will appear|text |text |
|in column  |will |will |
|A.         |appe-|appe-|
|           |r in |r in |
|           |colu-|colu-|
|           |mn B.|mn C.|
|100        |200  |300  |
|___________|_____|_____|


How can I create a table which spans 2 pages, in this manner?

Update:

Until the bug is fixed, I need a solution for my book. I have tried using linetables with the solution to How to set two or more paragraphs to use the same amount of vertical space? to ensure that the three paragraphs align properly. This is what I have attempted:

\setuppapersize[A5][A4, landscape]
\setuparranging[2SIDE]
\newdimen\maxbufferheight
\def\placebuffertomaximumheight[#1]%
{\maxbufferheight\zeropoint
\processcommalist[#1]\domeasurebuffermaxheight
\processcommalist[#1]\doplacebuffertomaxheight}
\def\domeasurebuffermaxheight#1%
{\setbox\scratchbox\vbox{\getbuffer[#1]}%
\scratchdimen\ht\scratchbox
\ifdim\scratchdimen>\maxbufferheight
\maxbufferheight=\scratchdimen
\fi}
\def\doplacebuffertomaxheight#1%
{\ruledvbox to \maxbufferheight
{\getbuffer[#1]}%
\blank[none]}
\setuppagenumbering[alternative=doublesided]
\startsetups twopagealign:before
\page [left]
\setuplinetable [n=3]
\setuplinetable [c][1] [width=\textwidth]
\setuplinetable [c][2] [width=.5\textwidth]
\setuplinetable [c][3] [width=.5\textwidth]
\startlinetable
\stopsetups
\definestartstop [twopagealign]
[
before=\setups{twopagealign:before},
after={\stoplinetable\page},
]
\define[3]\myalign{\NC#1\NC#2\NC#3\NC\NR}
\define[3]\makeinbuffer{
\myalign{
\startbuffer[one]
#1
\stopbuffer
}{
\startbuffer[two]
#2
\stopbuffer
}{
\startbuffer[three]
#3
\stopbuffer
}
\placebuffertomaximumheight[one,two,three]
}
\starttext
\starttwopagealign
\myalign {\input knuth} {\input tufte} {\input ward}
\makeinbuffer{\input ward}{\input tufte}{\input ward}
\stoptwopagealign
\stoptext

-
Isn't this just a mutipage table spread over teo pages? Have you looked into linetables? –  Aditya Apr 1 '12 at 23:59
Yes, it is essentially a large table. I did not know about linetables. It seems to be exactly what I was looking for. –  Village Apr 2 '12 at 3:40
There are very few ConTeXt users on this site. Most of the context users hang around on the context mailing list. I would suggest posting some of your unanswered questions there. –  Aditya Apr 7 '12 at 7:03

So, here's another attempt to produce the desired layout. It's based on Adityas solution to question How to set two or more paragraphs to use the same amount of vertical space? (I like his buffers approach more than my two-pass data hack).

\newdimen\maxbufferheight
\newcount\nofmeasuredcolumns
\newcount\nofmeasuredrows
\newcount\ltcolumncount

\def\domeasurebuffermaxheight#1#2{%
\scratchdimen\getvalue{linetblwd-#2width}
\setbox\scratchbox\vbox
\framed
[
frame=off,
offset=0pt,
boffset=2ex, % hmm, don't know why
width=\the\scratchdimen,
align=normal,
]{\getbuffer[#1]}
\scratchdimen\ht\scratchbox
\ifdim\scratchdimen>\maxbufferheight
\maxbufferheight=\scratchdimen
\fi}

\def\doplacebuffertomaxheight#1{%
%\ruledvbox to \maxbufferheight
\vbox to \maxbufferheight
{\getbuffer[#1]}%
\blank[none]}

\def\startcolumn{%
\grabbufferdata
[measuredcolumn-\the\nofmeasuredrows-\the\nofmeasuredcolumns]
[startcolumn]
[stopcolumn]}

\def\stopcolumn{}

\def\startrow{%
\nofmeasuredcolumns\zerocount

\def\stoprow{%
\maxbufferheight\zeropoint}

\def\starttwopagealign{%
\nofmeasuredrows\zerocount}

\def\stoptwopagealign{%
\page [left]
\setuplinetable [n=\the\nofmeasuredrows]
\dorecurse{\the\ltcolumncount}{%
\normalexpanded{%
\setuplinetable [c][\recurselevel]
[width=\getvalue{linetblwd-\recurselevel width}]}}
\startluacode
context.startlinetable()
for i=1, tex.count.nofmeasuredrows do
for j=1, tex.count.nofmeasuredcolumns do
context.domeasurebuffermaxheight("measuredcolumn-" .. i .. "-" .. j, j)
end
for j=1, tex.count.nofmeasuredcolumns do
context.NC()
context.doplacebuffertomaxheight("measuredcolumn-" .. i .. "-" .. j)
end
context.NC()
context.NR()
end
context.stoplinetable()
\stopluacode
\page
}

\def\setuplinetablewidth {\dodoubleempty\dosetuplinetablewidth}

\def\dosetuplinetablewidth [#1][#2]{%
\getparameters [linetblwd-#1] [#2]}


This is how you use the code:

\setuplinetablewidth [1] [width=\textwidth]
\setuplinetablewidth [2] [width=.5\textwidth]
\setuplinetablewidth [3] [width=.5\textwidth]

\starttext

\input knuth

\starttwopagealign

\startrow
\startcolumn
\input ward
\stopcolumn

\startcolumn
Foo
\stopcolumn

\startcolumn
Bar
\stopcolumn
\stoprow

\startrow
\startcolumn
Foo
\stopcolumn

\startcolumn
Bar
\stopcolumn

\startcolumn
\input knuth
\stopcolumn
\stoprow

\stoptwopagealign

\stoptext


The result:

The screenshot was made with \ruledvbox instead of \vbox to visualize the table cells.

# How it works

The basic idea is to collect the data in buffers, which is done by the \startcolumn commands.

Then the maximum height per row is calculated (to work around the bug), this should be done by linetables. It is then wrapped in a linetable and the calculated height per row is provided explicitly.

The column width is set as follows:

\setuplinetablewidth [1] [width=\textwidth]
\setuplinetablewidth [2] [width=.5\textwidth]
\setuplinetablewidth [3] [width=.5\textwidth]


For the \page [left] command to work, you need a recent ConTeXt, there was a bug, which had been fixed recently. This code is quite hackish and should be considered only as a temporary work around. Depending on the content, you have to play with the boffset value. In my tests a value between 2ex and 5ex was good. I have no idea why this is necessary and where the wrong box size comes from.

-

I don't have a real solution, but I try to get you started (thanks to Aditya for the linetables hint). Here's the code and the corresponding output:

\setuppagenumbering [alternative=doublesided]

\startsetups twopagealign:before
\page [left]
\setuplinetable [n=3]
\setuplinetable [c][1] [width=\textwidth]
\setuplinetable [c][2] [width=.5\textwidth]
\setuplinetable [c][3] [width=.5\textwidth]
\startlinetable
\stopsetups

\definestartstop [twopagealign]
[
before=\setups{twopagealign:before},
after={\stoplinetable\page},
]
\define[3]\myalign{\NC#1\NC#2\NC#3\NC\NR}

\starttext
\starttwopagealign
\myalign {\input knuth} {\input tufte} {\input ward}
\myalign {\tfd 100}     {\tfd 200}     {\tfd 300}
\stoptwopagealign
\stoptext


The result:

The code should be self-explanatory. It is a linetable with the necessary setups (in case you use more linetables in you document) enclosed in \page commands.

However, it does not work as expected. Since linetables are processed per page, the alignment of the rows doesn't work across pages, as you can see in the screenshot (the 100 is not aligned with the 200, though the 300 is).

-
This looks like a bug in linetables. Can you post a bug-report to the mailing list? –  Aditya Apr 4 '12 at 21:12
Done. But it seems unlikely to be fixed soon. Hans' response: “[…]adding some support for the height alignment is not too complex[…]but is not on the agenda for now[…]”. Bug report –  Marco Apr 10 '12 at 17:58