在 OTR(Plain TeX)中重新排列块(诗歌)

在 OTR(Plain TeX)中重新排列块(诗歌)

我有一个问题,我认为最好通过输出例程来解决。这看起来像是适度的 TeX 魔法,所以在我陷入错误的方法之前,我想我会描述一下这个问题,看看是否有人支持它或建议其他方法。我很高兴收到一些关于我可以自己解决的解决方案的指示,就像完整的解决方案一样。

笔记我在这里使用 Plain TeX,部分原因是我想学习高级魔法。我对 LaTeX 解决方案不是特别感兴趣。

我正在排版一本翻译的诗集。我想保留原文和译文,所以我的输入应该大致如下:

<Poem #1 English>

<Poem #1 Spanish>

<Poem #2 English>

<Poem #2 Spanish>

我想在左页显示英文,在右页显示西班牙文。我想先用一种语言标记这首诗,然后再用另一种语言标记。简而言之,TeX 可以通过两种方式帮助我:

  1. 如果这首诗很长,那么两种语言的第一页应该在前两页相对而行,然后是第二页,在第三页和第四页也用两种语言写成,等等。我不想必须“目测”并自己将诗切成块。

  2. 如果这首诗很短(即少于 1/2 页),我希望两面都有诗歌,如下:

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

我很乐意在我的宏和输入中添加任何必要的东西来实现这一点,我只是不想手动进行重新排序。

我觉得这听起来像是 OTR 的工作。我正在尝试了解如何解决这个问题。

我的第一个想法是避免插入,只需触发页面生成器并使用标记即可。当我设置诗歌的语言时,我会留下一个标记;如果 topmark 是英语并且页面是均匀的,则发送它。这让我想到了这一点:

\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}

我修改了我的宏\startpoem\startspanishpoem做出了相应的标记;我有一个mark{}\stoppoem但这似乎只会产生这种结构不全面的情况。

这似乎根本不起作用;我收到很多警告(我假设这是由于我用 咬掉盒子底部后,盒子底部underfull没有可拉伸胶水 / 造成的)。\vfil\vsplit

此时,我觉得我已经陷入了困境。我想知道我是否应该使用插入来产生这种效果。任何指示都将不胜感激!

编辑:我现在尝试通过插入来解决它,我认为效果会更好一些:

\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}

这看起来更有希望,但我看到了一些问题/疑问:

  • 这种制作输出例程的方法合理吗?我的意思是,重新排列内容box255,然后调用另一个输出例程。
  • 我似乎在退出时丢失了格式。这是使用的副作用\vsplit还是我只是错过了其他细节?
  • 等等的正确值是什么\count\EnglishIns?我担心的是,如果我在一页上积累了大量错误语言的材料,即使我想发布下一种语言,它也会最终出现在 OTR 中。这是一个真正的问题吗?如果是这样,正确的值是什么,还是取决于提前知道最长的诗?

谢谢!

答案1

恕我直言,您不需要重新定义输出例程。

\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

相关内容