10

I have a problem that I think would best be solved by an output routine. It seems like an act of moderate TeX wizardry so before I get stuck in the weeds on a wrong approach I thought I would describe the problem and see if anyone endorses it or suggests something else. I'm just as happy to receive some pointers towards the solution that I can work out myself as the complete solution.

Note I'm using Plain TeX here, partly because I want to learn the advanced wizardry. I'm not especially interested in a LaTeX solution.

I am typesetting a collection of poetry in translation. I want to keep the origin with the translation so my input should be shaped roughly like this:

<Poem #1 English>

<Poem #1 Spanish>

<Poem #2 English>

<Poem #2 Spanish>

I want the English on the left page and the Spanish on the right page. I would like to mark up the poem in one language and then the other. So in short, there are two ways TeX can help me:

  1. If the poem is very long, the first page of both languages should be facing each other on the first two pages, then the second page. in both languages on the third and fourth page, etc. I don't want to have to "eyeball it" and cut the poem into chunks myself.

  2. If the poem is very short (i.e. less than 1/2 the page) I'd like two poems on both sides, like this:

    <short English A>    |    <short Spanish A>
                         |
    <short English B>    |    <short Spanish B>
    p.2                                     p.3
    

I'm happy to add whatever is necessary to my macros and input to make this happen, I just don't want to manually do the reordering.

This sounds like a job for the OTR to me. I'm trying to see how to approach this problem.

My first thought is to avoid insertions and just do it by triggering the page builder and using marks. I'd leave a mark when I set the language of the poem; if topmark is English and the page is even, ship it. This leads me to this:

\newbox\EnglishBox
\newbox\SpanishBox
\def\alternatingoutput{%
  % If we just read some English, stick it in the English box
  \if E\firstmark\setbox\EnglishBox\vbox{\unvbox\EnglishBox \unvbox255}\fi
  % If we just read some Spanish, stick it in the Spanish box
  \if S\firstmark\setbox\SpanishBox\vbox{\unvbox\SpanishBox \unvbox255}\fi
  % If we're on an even page, emit some English; otherwise some Spanish
  \ifodd\pageno%
    \setbox0\vsplit\SpanishBox to \vsize\shipout\box0\advancepageno
  \else%
    \setbox0\vsplit\EnglishBox to \vsize\shipout\box0\advancepageno
  \fi}

I modified my macros \startpoem and \startspanishpoem to make the appropriate mark; I had a mark{} in \stoppoem but that only seemed to create situations in which this if structure was not comprehensive.

This doesn't seem to do it at all; I get a lot of underfull warnings (which I assume are caused by not having stretchable glue / \vfil on the bottom of the box after I bite it off with \vsplit).

At this point I think I'm in pretty far over my head. I'm wondering if I should be using insertions instead to produce this effect. Any pointers would be greatly appreciated!

Edit: I've now tried to solve it with insertions, which I think is going somewhat better:

\newinsert\EnglishIns
\newinsert\SpanishIns

\count\EnglishIns=1000    \count\SpanishIns=1000
\skip \EnglishIns=0pt     \skip \SpanishIns=0pt
\dimen\EnglishIns=\vsize  \dimen\SpanishIns=\vsize

\def\poemoutput{%
  \ifodd\pageno%
    \setbox0\vsplit\SpanishIns to\vsize%
  \else%
    \setbox0\vsplit\EnglishIns to\vsize%
  \fi
  \setbox255\vbox{\box0\box255\vfill}
  \plainoutput}

\output={\poemoutput}

This feels more promising, but I see a few problems / questions:

  • Is this approach to making an output routine reasonable? I mean, rearranging what's in box255 and then invoking another output routine.
  • I seem to be losing formatting on the way out. Is that a side effect of using \vsplit or have I just missed some other detail?
  • What are the right values for \count\EnglishIns etc.? My fear is that if I accumulate a lot of material for the wrong language on one page it will wind up in the OTR even though I want to ship out the next language. Is this a real problem? If so, what are the right values, or does it depend on knowing in advance the longest poem?

Thanks!

  • @wipet This is probably one for you. – Andrew Jun 25 '15 at 19:07
6
+100

IMHO, you needn't to redefine output routine.

\def\Epoem{\epoem\epoem\epoem\epoem\epoem} 
\def\EEpoem{\Epoem\Epoem\Epoem\Epoem\Epoem}
\def\Spoem{\spoem\spoem\spoem\spoem\spoem} 
\def\SSpoem{\Spoem\Spoem\Spoem\Spoem\Spoem}

\newbox\ebox   \newbox\sbox
\newif\ifout

\def\outtwotexts{\par
   \setbox\ebox=\vbox{\unvbox\ebox\vfil}
   \setbox\sbox=\vbox{\unvbox\sbox\vfil}
   \loop 
      \outfalse
      \ifvoid\ebox\else \outtrue \fi
      \ifvoid\sbox\else \outtrue \fi
      \ifout  \ifvoid\ebox \null\vfil \else \vsplit\ebox to\vsize \fi \break
              \ifvoid\sbox \null\vfil \else \vsplit\sbox to\vsize \fi \break
   \repeat
}

\long\def\Etext#1{%
   \setbox\ebox=\vbox{\ifvoid\ebox\else \unvbox\ebox\lastbox \fi #1}%
}
\long\def\Stext#1{%
   \setbox\sbox=\vbox{\ifvoid\sbox\else \unvbox\sbox\lastbox \fi #1}%
   \outfalse
   \ifdim\ht\ebox>.5\vsize \outtrue \fi
   \ifdim\ht\sbox>.5\vsize \outtrue \fi
   \ifout \outtwotexts \fi
}
\def\endgame{\unvbox\ebox \vfil\break \unvbox\sbox \vfil\break}

\null\vfil\break % we need to start at empty page two

%% Now, wee put \Etext, \Stext, \Etext, \Stext, etc.
\Etext{\def\epoem{First English poem.\par}\EEpoem}
\Stext{\def\spoem{First Spanish poem.\par}\SSpoem}

\Etext{\def\epoem{Second long English poem.\par}\EEpoem\EEpoem\EEpoem}
\Stext{\def\spoem{Second long Spanish poem.\par}\SSpoem\SSpoem\SSpoem}

\endgame % we need to flush text shortest than .5\vsize (if exists)

\end
| improve this answer | |
  • Can you explain your algorithm a little bit? I'm having trouble seeing the forest for the trees… – Daniel Lyons Jun 29 '15 at 17:55
  • @DanielLyons \outtwotexts prints texts accumulated in \ebox and \sbox. Loop is here because texts can be longer than \vsize. One step of loop prints two pages (first from \ebox, second from \sbox). The loop is finished only if both boxes are empty. \Etext appends English text to \ebox. \Stext appends Spanish text to \sbox and runs \outtwotexts only if both boxes have \ht>.5\vsize. If you need explicitly close the page then you can add \vfil\break at the end of \Etext and \Stext parameter. – wipet Jun 30 '15 at 6:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.