[Tex/LaTex] How to create 6 parallel texts aligned by paragraph, with 3 texts on each page

parallelvertical alignment

I want to typeset a hexaglot work. Each language will occupy its own column, and there will be 3 columns on each page. The text will be aligned by paragraphs and headings.

Basically, I want something that looks like this:

              Left Page                                Right Page
+--------------------------------------+ +--------------------------------------+
| Heading    | Тема 1     | Primero    | | Χαίρετε!   | 標題1       |    ספרות  |
| -------    | ---------  | ---------- | | ---------- | ---------- | ---------- |
| English t- | Це не рос- | No tengo   | | Πώς είσαι; | 其實我不知  |  פוליטיקה |
| ext taking | ійський т- | nada. Pero | | Καλό.      | 中國。      | לערך אינו |
| up 3 lines | екст а ук- | Juan tiene | |            | 我使用的是  | ציו ישראל |
|            | раїнській. |            | |            | 翻譯。      |    תבניות |
|            |            |            | |            |            |            |
| Heading 2  | Дуже довг- | Segundo    | | Ελληνική ε | 我喜歡牛肉!| בהיסטוריה |
| ---------- | ий Тема    | ---------- | | ίναι ωραία | ---------- | ---------- |
|            | ---------- |            | | ---------- |            |            |
| Text taki- | Круто!     | Estoy abu- | | Σ 'αγαπώ.  | 你喜歡牛肉  |   אם מפתח |
| ng up 2    |            | rrido.     | |            | 嗎?       |   קישורים |
|            |            |            | |            |            |    תקשורת |
+--------------------------------------+ +--------------------------------------+

I looked at the parallel library but I couldn't figure out how to put in 3 columns. I also looked at parcolumns but I couldn't get text the two pages to line up.

How could I go about doing this?

Best Answer

REVISED VERSION (AUTOMATED PAGEBREAK CONTROL):

As with the manual solution, one initializes a "special table" with \newspecialtable. Likewise, one enters any number of rows to the table with repeated invocations of the macro \sixby{}{}{}{}{}{}, once per row. In this case, however, if a row would be so large as to push to the next page, the double-page is broken at that point and the complete new row is bumped to the next double-page.

When all the rows are entered via \sixby, one employs \finishspecialtable, to clear out the straggler rows onto a final double-page. As a bonus, I added Russian and greek support to this MWE. I hope I am not inadvertantly cursing or using foreign foul language, as I just copied the foreign text from other pages on the site.

In case one doesn't spot it immediately, the table column width and overall maximum text height have been reset here (for demonstration purposes) to \def\colwidth{1in} and \textheight=4in\relax, respectively. They should be reset to appropriate values for actual use.

The \printtabtoks method came from Herbert at How to programmatically make tabular rows using `\whiledo` ?

EDITED to handle centering and quotes.

\documentclass[]{article}
\usepackage[T2A,T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[greek,russian,english]{babel}
\usepackage{ifthen}
\usepackage{calc}

\makeatletter
\newcounter{tabindex}
\newtoks\@tabtoks
\newcommand\addtabtoks[1]{%
  \@tabtoks\expandafter{\the\@tabtoks\stepcounter{tabindex}#1}}
\newcommand*\resettabtoks{\@tabtoks{}}
\newcommand*\synctabindex[1]{\setcounter{tabindex}{\value{#1}}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother

\def\colwidth{1in}
\newcounter{sptstartrow}
\newcounter{sptendrow}
\newcounter{entries}
\newcounter{pagerows}
\newlength\CurrentTableHeight
\newlength\CurrentRowHeight
\newsavebox\pagerow

\newcommand\newspecialtable{%
  \setcounter{sptendrow}{0}%
  \setcounter{entries}{0}%
  \setcounter{pagerows}{0}%
  \setlength\CurrentTableHeight{0pt}%
}

\makeatletter
\newcommand\sixby[6]{%
  \stepcounter{entries}%
  \expandafter\def\csname entryX\roman{entries}Xa\endcsname{#1}%
  \expandafter\def\csname entryX\roman{entries}Xb\endcsname{\foreignlanguage{russian}{#2}}%
  \expandafter\def\csname entryX\roman{entries}Xc\endcsname{#3}%
  \expandafter\def\csname entryX\roman{entries}Xd\endcsname{\textgreek{#4}}%
  \expandafter\def\csname entryX\roman{entries}Xe\endcsname{#5}%
  \expandafter\def\csname entryX\roman{entries}Xf\endcsname{#6}%
  \synctabindex{entries}%
  \sbox{\pagerow}{\formatcol{a}\formatcol{b}\formatcol{c}\formatcol{d}\formatcol{e}\formatcol{f}}%
  \setlength\CurrentRowHeight{\ht\pagerow+\dp\pagerow}%
  \addtolength\CurrentTableHeight{\CurrentRowHeight}%
  \ifdim\CurrentTableHeight>\textheight %
    \makespecialtable[\thepagerows]%
    \setcounter{pagerows}{0}%
    \setlength\CurrentTableHeight{\CurrentRowHeight}%
    \else\fi%
  \stepcounter{pagerows}%
}
\makeatother
\newcounter{index}
\newcommand\makespecialtable[1][\theentries]{%
  \setcounter{sptstartrow}{\thesptendrow}%
  \addtocounter{sptendrow}{#1}%
  \ifthenelse{\thesptendrow > \theentries}{\setcounter{sptendrow}{\theentries}}{}%
  \clearpage
  \setcounter{index}{\thesptstartrow}%
  \synctabindex{index}
  \resettabtoks%
  \whiledo{\theindex < \thesptendrow}{%
    \stepcounter{index}%
    \addtabtoks{%
      \csname entryX\roman{tabindex}Xa\endcsname &
      \csname entryX\roman{tabindex}Xb\endcsname &
      \csname entryX\roman{tabindex}Xc\endcsname & 
      \vphantom{\formatcol{d}\formatcol{e}\formatcol{f}}
      \\%
      \hline%
    }%
  }%
  \begin{tabular}{|p{\colwidth}|p{\colwidth}|p{\colwidth}|@{\extracolsep{-\tabcolsep}}l}%
   \hline%
   \printtabtoks%
  \end{tabular}%
  \clearpage
  \setcounter{index}{\thesptstartrow}%
  \synctabindex{index}
  \resettabtoks%
  \whiledo{\theindex < \thesptendrow}{%
    \stepcounter{index}%
    \addtabtoks{%
      \csname entryX\roman{tabindex}Xd\endcsname &
      \csname entryX\roman{tabindex}Xe\endcsname &
      \csname entryX\roman{tabindex}Xf\endcsname &
      \vphantom{\formatcol{a}\formatcol{b}\formatcol{c}}
      \\%
      \hline%
    }%
  }%
  \begin{tabular}{|p{\colwidth}|p{\colwidth}|p{\colwidth}|@{\extracolsep{-\tabcolsep}}l}%
   \hline%
   \printtabtoks%
  \end{tabular}%
}

\newcommand\formatcol[1]{%
   \parbox[t]{\colwidth}{\csname entryX\roman{tabindex}X#1\endcsname\strut}%
}

\newcommand\finishspecialtable{\makespecialtable}

\textheight=4in\relax
\begin{document}
\centering
\newspecialtable
\sixby
  {Row 1: Title of {\centering \bfseries CENTERED\par} column 1 maybe a bit longer than column 3}%
  {Текст на русском языке}%
  {No tengo  nada. Pero Juan\begin{quote}\bfseries QUOTE\end{quote} tiene}%
  {Πώς είσαι Καλό.}%
  {while this is a test of a particularly extended line spanning a
    number of rows, more than all the others.  And I really mean more than all the others}%
  {T}
\sixby
  {Row 2: this is a test of a particularly extended line spanning a
    number of rows, more than all the others}%
  {Це не російський текст а українській.}%
  {Segundo}%
  {φύσις}%
  {Here is some text for this entry}%
  {column 6 entry maybe a bit longer than column 5}
\sixby
  {Row 3: this is a test of a longer line}%
  {Дуже довгий Тема}%
  {Estoy aburrido.}%
  {Και άλλο ελληνικό κείμενο}%
  {}%
  {column 6 entry maybe a bit longer than column 5}
\sixby
  {Row 4: this is a test of an extended rows}%
  {Круто!}%
  {Estoy aburrido.}%
  {ἀλλ' οὐ λέγουσι τὸ διὰ τί περὶ οὐδενός, οἷον διὰ}%
  {final text}%
  {column 6 entry maybe a bit longer than column 5}%
\sixby
  {Row 5: Title of column 1 maybe a bit longer than column 3}%
  {Текст на русском языке}%
  {No tengo  nada. Pero Juan tiene}%
  {Πώς είσαι Καλό.}%
  {while this is a test of a particularly extended line spanning a
    number of rows, more than all the others.  And I really mean more than all the others}%
  {T}
\sixby
  {Row 6: this is a test of a longer line}%
  {Це не російський текст а українській.}%
  {Segundo}%
  {φύσις}%
  {Here is some text for this entry}%
  {column 6 entry maybe a bit longer than column 5}
\sixby
  {Row 7: this is a test of an extended rows}%
  {Круто!}%
  {Estoy aburrido.}%
  {ἀλλ' οὐ λέγουσι τὸ διὰ τί περὶ οὐδενός, οἷον διὰ}%
  {final text}%
  {column 6 entry maybe a bit longer than column 5}%
\sixby
  {Row 8: Title of column 1 maybe a bit longer than column 3}%
  {Текст на русском языке}%
  {No tengo  nada. Pero Juan tiene}%
  {Πώς είσαι Καλό.}%
  {while this is a test of a particularly extended line spanning a
    number of rows, more than all the others.  And I really mean more than all the others}%
  {T}
\finishspecialtable
\end{document}

Here are shown the first two pages of output. The MWE puts out 6 pages of output, demonstrating the auto-pagebreaks

enter image description here

enter image description here

ORIGINAL SOLUTION (MANUAL PAGEBREAK CONTROL):

One initializes a "special table" with \newspecialtable. Then, one enters any number of rows to the table with repeated invocations of the macro \sixby{}{}{}{}{}{}, once per row. When all the rows are entered, one employs \makespecialtable[rows], where "rows" is the number of rows to printout, so as not to extend past a page break. Multiple invocations of \makespecialtable will proceed through the rows, until the table rows are exhausted.

In this MWE, I use \sixby four times. Then I output the table with

\makespecialtable[3]
\makespecialtable

In this way, rows(1-3)cols(1-3) appear on p.1, rows(1-3)cols(4-6) appear on page 2, row(4)cols(1-3) appear on p.3 and row(4)cols(4-6) appear on page 4.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{ifthen}

\makeatletter
\newcounter{tabindex}
\newtoks\@tabtoks
\newcommand\addtabtoks[1]{%
  \@tabtoks\expandafter{\the\@tabtoks\stepcounter{tabindex}#1}}
\newcommand*\resettabtoks{\@tabtoks{}}
\newcommand*\synctabindex[1]{\setcounter{tabindex}{\value{#1}}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother

\def\colwidth{1in}
\newcounter{sptstartrow}
\newcounter{sptendrow}
\newcounter{entries}

\newcommand\newspecialtable{%
  \setcounter{sptendrow}{0}%
  \setcounter{entries}{0}%
}

\makeatletter
\newcommand\sixby[6]{%
  \stepcounter{entries}%
  \expandafter\protected@edef\csname entryX\roman{entries}Xa\endcsname{#1}%
  \expandafter\protected@edef\csname entryX\roman{entries}Xb\endcsname{#2}%
  \expandafter\protected@edef\csname entryX\roman{entries}Xc\endcsname{#3}%
  \expandafter\protected@edef\csname entryX\roman{entries}Xd\endcsname{#4}%
  \expandafter\protected@edef\csname entryX\roman{entries}Xe\endcsname{#5}%
  \expandafter\protected@edef\csname entryX\roman{entries}Xf\endcsname{#6}%
}
\makeatother
\newcounter{index}
\newcommand\makespecialtable[1][\theentries]{%
  \setcounter{sptstartrow}{\thesptendrow}%
  \addtocounter{sptendrow}{#1}%
  \ifthenelse{\thesptendrow > \theentries}{\setcounter{sptendrow}{\theentries}}{}%
  \clearpage
  \setcounter{index}{\thesptstartrow}%
  \synctabindex{index}
  \resettabtoks%
  \whiledo{\theindex < \thesptendrow}{%
    \stepcounter{index}%
    \addtabtoks{%
      \csname entryX\roman{tabindex}Xa\endcsname &
      \csname entryX\roman{tabindex}Xb\endcsname &
      \csname entryX\roman{tabindex}Xc\endcsname & 
      \vphantom{%
        \parbox[t]{\colwidth}{\csname entryX\roman{tabindex}Xd\endcsname\strut}%
        \parbox[t]{\colwidth}{\csname entryX\roman{tabindex}Xe\endcsname\strut}%
        \parbox[t]{\colwidth}{\csname entryX\roman{tabindex}Xf\endcsname\strut}%
      }
      \\%
      \hline%
    }%
  }%
  \begin{tabular}{|p{\colwidth}|p{\colwidth}|p{\colwidth}|@{\extracolsep{-\tabcolsep}}l}%
   \hline%
   \printtabtoks%
  \end{tabular}%
  \clearpage
  \setcounter{index}{\thesptstartrow}%
  \synctabindex{index}
  \resettabtoks%
  \whiledo{\theindex < \thesptendrow}{%
    \stepcounter{index}%
    \addtabtoks{%
      \csname entryX\roman{tabindex}Xd\endcsname &
      \csname entryX\roman{tabindex}Xe\endcsname &
      \csname entryX\roman{tabindex}Xf\endcsname &
      \vphantom{%
        \parbox[t]{\colwidth}{\csname entryX\roman{tabindex}Xa\endcsname\strut}%
        \parbox[t]{\colwidth}{\csname entryX\roman{tabindex}Xb\endcsname\strut}%
        \parbox[t]{\colwidth}{\csname entryX\roman{tabindex}Xc\endcsname\strut}%
      }%
      \\%
      \hline%
    }%
  }%
  \begin{tabular}{|p{\colwidth}|p{\colwidth}|p{\colwidth}|@{\extracolsep{-\tabcolsep}}l}%
   \hline%
   \printtabtoks%
  \end{tabular}%
}

\begin{document}
\newspecialtable
\sixby
  {Row 1: Title of column 1 maybe a bit longer than column 3}%
  {this is a test of a longer line}%
  {BC}%
  {while this is a test of a particularly extended line spanning a
    number of rows, more than all the others.  And I really mean more than all the others}%
  {xcxcx}%
  {T}
\sixby
  {Row 2: this is a test of a longer line}%
  {Here is some text for this entry}%
  {while this is a test of a particularly extended line spanning a
    number of rows, more than all the others}%
  {F}%
  {T}%
  {column 6 entry maybe a bit longer than column 5}
\sixby
  {Row 3: this is a test of a longer line}%
  {BC}%
  {F}%
  {T}%
  {while this is a test of a particularly extended line spanning a
    number of rows, more than all the others}%
  {column 6 entry maybe a bit longer than column 5}
\sixby
  {Row 4: this is a test of an extended rows}%
  {x}%
  {a word}%
  {column 6 entry maybe a bit longer than column 5}
  {final line}%
  {}%
\centering
\makespecialtable[3]% Print 3 rows of the table (so as not to exceed page boundary)
\makespecialtable
\end{document}

enter image description here

enter image description here