简单来说,我想让我的文档的一小部分看起来分为两列。
但是,由于大部分内容应该放在一栏中,我有点怀疑是否会与内容纠缠在一起,\pagecontent
因为\output
它只占不到 1 页甚至几段内容。(如果这是最好的方式,我很乐意接受)
那么,有人可以给我一些关于在纯 TeX 中的普通文档中放置两列部分的见解吗?
非常感谢!
答案1
前段时间我为 Plan TeX 编写了一个输出例程,支持多列并具有正确的浮点顺序。如果您感兴趣请告诉我。:)
编辑:这是我承诺的解决方案。
\catcode`\@=11
% \protected\def\glet{\global\let} % if you do not use LuaTeX
\def\raggedbottom{\global\r@ggedbottomtrue} % if you are interested in grid typesetting
\newdimen\fullhsize
\newdimen\fullvsize
\fullhsize 20.5cm% change as you like
\fullvsize 26\baselineskip
\advance\fullvsize by \topskip
%
\hsize\fullhsize
\vsize\fullvsize
% Help macros:
\def\@gobble#1{}
\newdimen\@savsk
\newcount\@savsf
\def\@bsphack{% from LaTeX
\relax
\ifhmode
\@savsk\lastskip
\@savsf\spacefactor
\fi}
\def\@esphack{%
\relax
\ifhmode
\spacefactor\@savsf
\ifdim\@savsk>\z@
\ifdim\lastskip=\z@
\nobreak \hskip\z@skip
\fi
\ignorespaces
\fi
\fi}
\maxdeadcycles100
\newdimen\@colroom \@colroom\fullvsize% similar to LaTeX
\newdimen\@colht \@colht\fullvsize
\newinsert\bx@A
\newinsert\bx@B
\newinsert\bx@C
\newinsert\bx@D
\newinsert\bx@E
\newinsert\bx@F
\newinsert\bx@G
\newinsert\bx@H
\newinsert\bx@I
\newinsert\bx@J
\newinsert\bx@K
\newinsert\bx@L
\newinsert\bx@M
\newinsert\bx@N
\newinsert\bx@O
\newinsert\bx@P
\newcount\@topnum% float parameters, adjust as you like
\newcount\maxtopnum \maxtopnum\thr@@
\newdimen\@toproom
\newdimen\maxtoproom \maxtoproom.4\fullvsize
\newcount\@botnum
\newcount\maxbotnum \maxbotnum\tw@
\newdimen\@botroom
\newdimen\maxbotroom \maxbotroom.3\fullvsize
\newcount\@dbltopnum
\newcount\maxdbltopnum \maxdbltopnum\tw@
\newdimen\@dbltoproom
\newdimen\maxdbltoproom \maxdbltoproom.4\fullvsize
\newcount\@botnum
\newcount\maxbotnum \maxbotnum\tw@
\newdimen\@botroom
\newdimen\maxbotroom \maxbotroom.3\fullvsize
\newskip\floatsep
\floatsep\baselineskip
\newif\if@insert
\newif\if@trybottom
\newif\if@topinsblocked
\newif\if@dbltopinsblocked
\def\@empty{}
\def\@freelist{\bx@A\bx@B\bx@C\bx@D\bx@E\bx@F\bx@G\bx@H\bx@I\bx@J
\bx@K\bx@L\bx@M\bx@N\bx@O\bx@P}
\let\@currlist\@empty
\let\@toplist\@empty
\let\@botlist\@empty
\let\@dbltoplist\@empty
\let\@deferlist\@empty
\def\@addto#1#2{% #1: list, #2: box
\xdef#1{#1#2}}
\def\@next#1#2{% #1: macro for the box, #2: list
\xdef#1{\expandafter\@firstofmany#2!}%
\xdef#2{\expandafter\@gobble#2}}
\newcount\@floatpenalty
\def\float#1{%
\ifhmode
\@bsphack
\@floatpenalty-30000\relax
\else
\@floatpenalty-35000\relax
\fi
\@next\@currbox\@freelist
\global\count\@currbox#1\relax
\global\setbox\@currbox\vbox\bgroup
\parindent\z@ \parskip\z@}
\def\endfloat{\par\vskip\z@\egroup
\@addto\@currlist\@currbox
\ifnum\@floatpenalty <-30000\relax
\penalty -40000\relax
\dimen@\prevdepth
\vbox{}%
\prevdepth\dimen@
\penalty\@floatpenalty
\else
\vadjust{\penalty-40000\relax \vbox{}\penalty\@floatpenalty}%
\@esphack
\fi}
\def\dblfloat#1{%
\ifhmode
\@bsphack
\@floatpenalty-30000\relax
\else
\@floatpenalty-35000\relax
\fi
\@next\@currbox\@freelist
\global\count\@currbox-#1\relax
\global\setbox\@currbox\vbox\bgroup
\hsize\fullhsize
\parindent\z@ \parskip\z@}
\def\enddblfloat{\par\vskip\z@\egroup
\@addto\@currlist\@currbox
\ifnum\@floatpenalty <-30000\relax
\penalty -40000\relax
\dimen@\prevdepth
\vbox{}%
\prevdepth\dimen@
\penalty\@floatpenalty
\else
\vadjust{\penalty-40000\relax \vbox{}\penalty\@floatpenalty}%
\@esphack
\fi}
\def\@nextboxcnt{%
\expandafter\expandafter\expandafter
\count\expandafter\@firstofmany\@deferlist!}
\def\@nextboxht{%
\expandafter\expandafter\expandafter
\ht\expandafter\@firstofmany\@deferlist!}
\def\@firstofmany#1#2!{#1}
\def\fullline{\hbox to\fullhsize}
\def\makeheadline{\vbox to\z@{\vskip-22.5\p@
\fullline{\vbox to8.5\p@{}\the\headline}\vss}\nointerlineskip}
\def\makefootline{\baselineskip24\p@\lineskiplimit\z@\fullline{\the\footline}}
\footline={\hss\tenrm\folio\hss}
\headline={\hss\tenrm\folio\hss}
\newif\if@twocolumn
\newif\if@threecolumn% not implemented yet
\newif\if@multicolumn
\newif\if@firstcolumn \@firstcolumntrue
\newif\if@secondcolumn \@secondcolumnfalse
\newbox\firstcolumn
\newbox\secondcolumn
\def\columnbox{\leftline{\pagebody}}% similat to the example from the TeX book
\newdimen\columnsep
\columnsep.5cm
\def\@outputonecol{\shipout\vbox{\makeheadline\pagebody\makefootline}%
\advancepageno}
\def\onecolumn{\clearpage
\global\hsize\fullhsize
\global\@twocolumnfalse
\global\@multicolumnfalse}
\def\twocolumn{\clearpage
\global\hsize\fullhsize
\global\advance\hsize-\columnsep
\global\divide\hsize\tw@
\global\@twocolumntrue \global\@firstcolumntrue
\global\@multicolumntrue}
\def\@outputdblcol{\if@firstcolumn
\global\setbox\firstcolumn=\columnbox
\global\@firstcolumnfalse
\else
\doubleformat
\advancepageno
\global\@firstcolumntrue
\global\@dbltopinsblockedfalse
\global\@colht\fullvsize\fi}
\def\doubleformat{\shipout\vbox{%
\makeheadline
\ifx\@dbltoplist\@empty\else
\loop
\@next\@dbltopbox\@dbltoplist
\@addto\@freelist\@dbltopbox
\box\@dbltopbox
\vskip\floatsep
\unless\ifx\@dbltoplist\@empty\repeat
\fi
\fullline{\box\firstcolumn\hfil\columnbox}%
\makefootline}}
\output{%
\ifnum \outputpenalty<-\@M%B
\@specialoutput
\else%B
\if@twocolumn%A
\@outputdblcol
\else
\@outputonecol
\fi%A
\global\@topinsblockedfalse
\global\@colroom\@colht
\global\@topnum\z@
\global\@toproom\z@
\global\@botnum\z@
\global\@botroom\z@
%
\if@multicolumn
\ifx\@deferlist\@empty\else
% dbl top floats
\loop
\@inserttrue
\ifnum\@nextboxcnt>\m@ne \@insertfalse\fi
\ifnum\@nextboxcnt<-2\relax \@insertfalse\fi
\if@firstcolumn\else \@insertfalse\fi
\ifnum\@dbltopnum<\maxdbltopnum \else \@insertfalse\fi
\ifnum\@dbltopnum>\z@
\ifdim\maxdbltoproom<\dimexpr\@dbltoproom+\@nextboxht+\floatsep\relax
\@insertfalse\fi\fi
\if@insert
\@next\@nextbox\@deferlist
\@addto\@dbltoplist\@nextbox
\global\advance\@colht-\dimexpr\ht\@nextbox+\floatsep\relax
\global\advance\@colroom-\dimexpr\ht\@nextbox+\floatsep\relax
\global\advance\@dbltoproom\dimexpr\ht\@nextbox+\floatsep\relax
\global\advance\@dbltopnum\@ne
\fi
\ifx\@deferlist\@empty \@insertfalse\fi
\if@insert
\repeat
%
\fi
\fi
%
\ifx\@deferlist\@empty\else
% Top floats
\loop
\@inserttrue
\ifnum\@nextboxcnt<\z@ \@insertfalse\fi
\ifnum\@nextboxcnt>\tw@ \@insertfalse\fi
\ifnum\@topnum<\maxtopnum \else \@insertfalse\fi
\ifnum\@topnum>\z@
\ifdim\maxtoproom<\dimexpr\@toproom+\@nextboxht+\floatsep\relax
\@insertfalse\fi\fi
\if@insert
\@next\@nextbox\@deferlist
\@addto\@toplist\@nextbox
\global\advance\@colroom-\dimexpr\ht\@nextbox+\floatsep\relax
\global\advance\@toproom\dimexpr\ht\@nextbox+\floatsep\relax
\global\advance\@topnum\@ne
\fi
\ifx\@deferlist\@empty \@insertfalse\fi
\if@insert
\repeat
%
\fi
%
\ifx\@deferlist\empty\else
% Bottom floats:
\loop
\@inserttrue
\ifnum\@nextboxcnt<\tw@ \@insertfalse\fi
\ifdim\@nextboxht>\@colroom \@insertfalse\fi
\ifnum\@botnum<\maxbotnum \else \@insertfalse\fi
\ifnum\@botnum>\z@
\ifdim\maxbotroom<\dimexpr\@botroom+\@nextboxht+\floatsep\relax
\@insertfalse\fi\fi
\if@insert
\@next\@nextbox\@deferlist
\@addto\@botlist\@nextbox
\global\advance\@colroom-\dimexpr\ht\@nextbox+\floatsep\relax
\global\advance\@botroom\dimexpr\ht\@nextbox+\floatsep\relax
\global\advance\@botnum\@ne
\fi
\ifx\@deferlist\@empty \@insertfalse\fi
\if@insert
\repeat
%
\fi
%
\fi%B
\ifnum\outputpenalty<-35000\relax
\global\vsize\maxdimen\else\global\vsize\@colroom\fi}
\def\@specialoutput{%
\ifnum\outputpenalty>-30000\relax%A
\dosupereject
\else%A
\ifnum\outputpenalty<-35000\relax%B
\ifnum\outputpenalty<-40000\relax \deadcycles\z@\fi
\global\setbox\@ne\vbox{\unvbox\@cclv}%
\else%B
\setbox8\box\@cclv
\dimen@\dimexpr\ht\@ne+\dp\@ne\relax
\unvbox\@ne
\ifvoid\footins\else\insert\footins{\unvbox\footins}\fi
%
\@inserttrue
\ifx\@deferlist\@empty \else \@insertfalse\fi
%
\@next\@currbox\@currlist
%
\ifcase\count\@currbox%0
\ifx\@deferlist\@empty \else \@insertfalse\fi
\ifx\@botlist\@empty \else \@insertfalse\fi
%\ifdim\ht\@currbox>\dimexpr\@colroom-5\baselineskip\relax \@insertfalse\fi
\ifdim\@colroom<\dimexpr\dimen@+\ht\@currbox+\tw@\floatsep+\thr@@%
\baselineskip\relax \@insertfalse\fi
\if@insert
\vskip\floatsep
\box\@currbox
\vskip\floatsep
\@addto\@freelist\@currbox
\global\@topinsblockedtrue
\global\@dbltopinsblockedtrue
\else
\count\@currbox\tw@
\@addto\@deferlist\@currbox
\fi
\or%1
\@inserttrue
\ifx\@deferlist\@empty \else \@insertfalse\fi
\ifx\@botlist\@empty \else \@insertfalse\fi
\if@topinsblocked \@insertfalse\fi
\ifnum\@topnum<\maxtopnum \else \@insertfalse\fi
\ifnum\@topnum>\z@
\ifdim\maxtoproom<\dimexpr\@toproom+\ht\@currbox+\floatsep\relax
\@insertfalse\fi\fi
\if@insert
\@addto\@toplist\@currbox
\global\advance\@colroom-\dimexpr\ht\@currbox+\floatsep\relax
\global\advance\@toproom\dimexpr\ht\@currbox+\floatsep\relax
\global\advance\@topnum\@ne
\else
\@addto\@deferlist\@currbox
\fi
%
\or%2
\@inserttrue
\@trybottomfalse
\ifx\@deferlist\@empty \else \@insertfalse\fi
\ifx\@botlist\@empty \else \@insertfalse\fi
\if@topinsblocked \@insertfalse\fi
\ifnum\@topnum<\maxtopnum \else \@insertfalse\fi
\ifnum\@topnum>\z@
\ifdim\maxtoproom<\dimexpr\@toproom+\ht\@currbox+\floatsep\relax
\@insertfalse\fi\fi
\if@insert
\@addto\@toplist\@currbox
\global\advance\@colroom-\dimexpr\ht\@currbox+\floatsep\relax
\global\advance\@toproom\dimexpr\ht\@currbox+\floatsep\relax
\global\advance\@topnum\@ne
\else
\ifx\@deferlist\@empty \@trybottomtrue
\else \@addto\@deferlist\@currbox\fi
\fi
%
\if@trybottom
\@inserttrue
\ifdim\ht\@currbox>\dimexpr\@colroom-\floatsep\relax \@insertfalse\fi
\ifnum\@botnum<\maxbotnum \else \@insertfalse\fi
\ifnum\@botnum>\z@
\ifdim\maxbotroom<\dimexpr\@botroom+\ht\@currbox+\floatsep\relax
\@insertfalse\fi\fi
\if@insert
\@addto\@botlist\@currbox
\global\advance\@colroom-\dimexpr\ht\@currbox+\floatsep\relax
\global\advance\@botroom\dimexpr\ht\@currbox+\floatsep\relax
\global\advance\@botnum\@ne
\else
\@addto\@deferlist\@currbox
\fi
%
\fi
%
\or%3
\@inserttrue
\ifx\@deferlist\@empty \else \@insertfalse\fi
\ifdim\ht\@currbox>\@colroom \@insertfalse\fi
\ifnum\@botnum<\maxbotnum \else \@insertfalse\fi
\ifnum\@botnum>\z@
\ifdim\maxbotroom<\dimexpr\@botroom+\ht\@currbox+\floatsep\relax
\@insertfalse\fi\fi
\if@insert
\@addto\@botlist\@currbox
\global\advance\@colroom-\dimexpr\ht\@currbox+\floatsep\relax
\global\advance\@botroom\dimexpr\ht\@currbox+\floatsep\relax
\global\advance\@botnum\@ne
\else
\@addto\@deferlist\@currbox
\fi
%
\fi
%
\ifnum\count\@currbox=\m@ne
\@inserttrue
\ifx\@deferlist\@empty \else \@insertfalse\fi
\if@firstcolumn \else \@insertfalse\fi
\ifx\@toplist\@empty \else \@insertfalse\fi
\ifx\@botlist\@empty \else \@insertfalse\fi
\ifx\@dblbotlist\@empty \else \@insertfalse\fi
\if@dbltopinsblocked \@insertfalse\fi
\ifnum\@dbltopnum<\maxdbltopnum \else \@insertfalse\fi
\ifnum\@dbltopnum>\z@
\ifdim\maxdbltoproom<\dimexpr\@dbltoproom+\ht\@currbox+\floatsep\relax
\@insertfalse\fi\fi
\if@insert
\@addto\@dbltoplist\@currbox
\global\advance\@colht-\dimexpr\ht\@currbox+\floatsep\relax
\global\advance\@colroom-\dimexpr\ht\@currbox+\floatsep\relax
\global\advance\@dbltoproom\dimexpr\ht\@currbox+\floatsep\relax
\global\advance\@dbltopnum\@ne
\else
\@addto\@deferlist\@currbox
\fi
\fi
%
\fi%B
\fi%A
}
\def\pagebody{\vbox to\@colht{\boxmaxdepth\maxdepth \pagecontents}}
\def\dosupereject{%
\ifvoid\footins%A
%
\setbox8\vsplit\@cclv to\z@ \unvbox8\relax
\setbox8\box\@cclv
\xdef\@deferlist{\@toplist\@botlist\@deferlist}%
\glet\@toplist\@empty \glet\@botlist\@empty
\global\@colroom\fullvsize
\global\@topinsblockedfalse
\global\@colroom\@colht
\global\@topnum\z@
\global\@toproom\z@
\global\@botnum\z@
\global\@botroom\z@
%
\setbox\@cclv\vbox{}
\ifx\@deferlist\empty%B
\else%B
\@inserttrue
\loop
\ifdim\@nextboxht>\@colroom \@insertfalse\fi
\if@insert
\@next\@floatbox\@deferlist
\@addto\@freelist\@floatbox
\global\advance\@colroom-\dimexpr\ht\@floatbox+\floatsep\relax
\global\setbox\@cclv\vbox{\unvbox\@cclv\box\@floatbox\vskip\floatsep}%
\fi
\ifx\@deferlist\@empty \@insertfalse\fi
\if@insert
\repeat
%
\setbox\@cclv\vbox to\colht{\unvbox\@cclv\vss}
%
\if@twocolumn
\@outputdblcol
\else
\@outputonecol
\fi
\global\@topinsblockedfalse
\global\@colroom\fullvsize
\global\@topnum\z@
\global\@toproom\z@
\global\@botnum\z@
\global\@botroom\z@
%
\fi%B
%
\ifx\@deferlist\@empty\else\supereject\fi
\else%A
\setbox\@cclv\vbox{\box\@cclv\vfil}
\if@twocolumn
\@outputdblcol
\else
\@outputonecol
\fi
\global\@topinsblockedfalse
\global\@colroom\fullvsize
\global\@topnum\z@
\global\@toproom\z@
\global\@botnum\z@
\global\@botroom\z@
\supereject
\fi}
\def\pagecontents{\ifx\@toplist\@empty\else
\loop
\@next\@topbox\@toplist
\@addto\@freelist\@topbox
\box\@topbox
\vskip\floatsep
\unless\ifx\@toplist\@empty\repeat
\fi
\dimen@=\dp\@cclv \unvbox\@cclv % open up \box255
\ifx\@botlist\@empty\else
\loop
\@next\@botbox\@botlist
\@addto\@freelist\@botbox
\vskip\floatsep
\box\@botbox
\unless\ifx\@botlist\@empty\repeat
\fi
\ifr@ggedbottom \kern-\dimen@ \vfil \fi
\ifvoid\footins\else % footnote info is present
\vskip\skip\footins
\footnoterule
\unvbox\footins\fi}
\def\eject{\vfill\par\break}
\def\supereject{\eject \write\m@ne{}\vbox{}\penalty -\@MM}
\def\clearpage{\supereject
\if@twocolumn \if@firstcolumn\else \null\eject \fi\fi}
\outer\def\bye{%
\supereject
\if@twocolumn \if@firstcolumn\else \null\eject \fi\fi
\end}
1. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
\float0 ABCD0 \vskip20pt\endfloat% \float0 is like \midinsert
\float1 ABCD2 \vskip20pt\endfloat% \float1 like \topinsert
\float1 ABCD3 \vskip20pt\endfloat
\float1 ABCD4 \vskip20pt\endfloat
\float1 ABCD5 \vskip20pt\endfloat
\float1 ABCD6a \vskip20pt\endfloat
\float3 ABCD6b \vskip20pt\endfloat% \float3 is like \bottominsert (not defined in plain.tex)
\float3 ABCD6c \vskip20pt\endfloat
2. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
\float1 ABCD7 \vskip20pt\endfloat
\float1 ABCD8 \vskip20pt\endfloat
3. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
浮点数的顺序保持不变(与 plain.tex 不同)。您可以像在 LaTeX 中一样在\onecolumn
和之间切换\twocolumn
。
警告:有些事情尚未实现:
\supereject
不处理 dblfloat。- 模式下的 dblfloats
\onecolumn
将导致问题。 - 超过 2 列尚未实现(不难)。
代码中注释不多,有问题可以提问。