两个想法:

两个想法:

我知道如何让multicol包在移动到下一列之前使用整个第一列:

\begin{multicols*}{3} 
....
\end{multicols*}

这在手册的第 2.2 节中提到过。但该节中还提到了 starred 环境“仅在顶层有效。” 手册解释说“在没有固定值的情况下,必须保持平衡才能确定框内柱高。”

我想知道的是,当已知包含框的高度时,是否有办法解决这个问题。

换句话说,如果我想写类似的东西

\begin{minipage}[t][4in]{10in}
\begin{multicols*}{3}
....
\end{multicols*}
\end{minipage}

并让multicol包认为它位于指定高度的页面上。

有人知道有什么解决方法吗?

我知道我可以将其用于\newgeometry给定页面。但是,我的页眉和页脚被移动了,我对此很不满意。此外,我通常不想将整个页面都用于这种多列格式。

这是页面设计的示例。虽然从图片上可能很难看出来。这是横向的 8.5x11 页面。

在此处输入图片描述

这是创建此图像的 MWE。这是一个非常奇怪的页面设计,但它满足了完成的文档的需求。

\documentclass{article}
%--------------------
\usepackage[top=0.35in,bottom=0.35in,width=4in,landscape,includefoot,includehead]{geometry}
%--------------------
\usepackage{fancyhdr}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}
\lhead{Left}\rhead{Right}
\pagestyle{fancy}
%--------------------
\usepackage{multicol}
\setlength{\columnseprule}{0.4pt}
\setlength{\columnsep}{0.25in}
%--------------------
\usepackage{lipsum}
\begin{document}

\lipsum[1]
\vspace{2ex}

\noindent
\hspace*{\dimexpr\textwidth/2}%
\hspace*{-5in}%
\begin{minipage}{0pt}
  \begin{minipage}[t][2.85in]{10in}
    \begin{multicols*}{4}
        \lipsum[1-2]
        \vspace{2in}        

        \vspace{2.85in}~
        \hspace*{\fill}.
    \end{multicols*}
  \end{minipage}
\end{minipage}

\vspace{2ex}
\lipsum[2]

\end{document}

该文档特意设计为具有极大的边距 - 因此页眉和页脚同样不应跨越整个页面以保持大边距的外观。

显然我可以达到我想要的效果,但我不想经历这些多列插入并手动放置足够的支柱以正确填充盒子的高度。

\hspace*{\fill}.顺便说一句,环境中的最后一个multicols只是插入那里,这样,当我裁剪图像时,裁剪不会剪掉太多的空白空间。

两个想法:

对于如何实现这一点,我有两个想法。但我都不知道如何实现。

准备工作

虽然对于最终版本,我希望能够选择我需要的列数,但为了解释我的想法,我假设我正在处理 4 列文本。

假设环境的总宽度为W,且\columnsep设置为s。那么环境内一列文本的宽度应为C=(W-3s)/4

假设环境的高度为H。由于我要格式化四列文本,每列的高度为H,因此如果将每列堆叠在一起,则每列的总有效高度接近4H

第一个想法

第一个使用 在单次运行下格式化多列环境pdflatex

思路如下:

(1)首先将文本格式化为只有一列宽度的文本C

我可以这样做:

\begin{lrbox}{\aebox}
  \begin{minipage}{<width=C>}
  ....TEXT....
  \end{minipage}
\end{lrbox}

(2)测量此列文本的高度,称之为h

\setlength{<height=h>}{\dimexpr\dp\aebox+\ht\aebox\relax}    

(3)如果h>4H,那么我就有问题了。我对考虑这个案例不感兴趣。

(4)如果h<4H,那么我会观察差异4H-h并创造尽可能多的支柱高度H适合4H-h和一个剩余支撑高度4H-h modulo H

假设各列从左到右的字母分别为ABCD。那么我将得到长度

\aestrutDheight      
\aestrutBheight      
\aestrutCheight      
\aestrutRheight <remainder height>

<PSEUDO-CODE>
let L=4H-h

while L > H
{
  <set a length for each iteration>
  \setlength{\aestrut[DBC]height}{<height=H>}
  L=L-H
}
\setlength{\aestrutRheight}{L}

(5)重新处理文本,但使用剩余支撑和别的支柱附录。

-此处的代码适用于文本足以跨越 3 列但不足以跨越 4 列的情况。

\begin{minipage}[t][<height=H>]{<width=C>}
\begin{multicols*}{4}
....TEXT....

\rule{0pt}{\aestrutRheight}

\rule{0pt}{\aestrutDheight}
\end{multicols*}
\end{minipage}

总的来说,我认为除了最后一步之外,我都能做到。一旦我使用了文本,我就失去了它,不知道如何重新处理它。

第二个想法

这个想法与第一个非常相似。但需要两次传递pdflatex

(1)尝试将文本格式化为 4 列平衡文本

\begin{lrbox}{\aebox}
\begin{minipage}{<width=W>}
\begin{multicols}{4}
....TEXT....
\end{multicols}
\end{minipage}
\end{lrbox}

(2)测量这个盒子的高度。

(3)计算该高度与目标高度的差值。

(4)计算所需支柱的长度,并将其写入文件中log

(5)在第二次重新运行时pdflatex,读取日志文件,然后将文本格式化为

\begin{minipage}[<height=H>]{<width=W>}
\begin{multicols*}{4}
...TEXT...
<insert struts determine by `log` file>
\end{multicols*}
\end{minipage}

但我不知道如何将这些信息写入文件log或如何从文件中读取log以创建必要的支柱。

更新:已经开始有一个可行的解决方案,但还不够。

我创建了以下解决方法。但有几件事我无法正确解决:

\begin{filecontents}{content.tex}
  Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
  vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum
  gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate
  a, magna. Donec vehicula augue eu neque. Pellentesque habitant morbi
  tristique senectus et netus et malesuada fames ac turpis egestas. Mauris
  ut leo. Cras viverra metus rhoncus sem. Nulla et lectus vestibulum urna
  fringilla ultrices. Phasellus eu tellus sit amet tortor gravida
  placerat. Integer sapien est, iaculis in, pretium quis, viverra ac,
  nunc. Praesent eget sem vel leo ultrices bibendum. Aenean faucibus. Morbi
  dolor nulla, malesuada eu, pulvinar at, mollis ac, nulla. Curabitur auctor
  semper nulla. Donec varius orci eget risus. Duis nibh mi, congue eu,
  accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci
  dignissim rutrum.

  Nam dui ligula, fringilla a, euismod sodales, sollicitudin vel,
  wisi. Morbi auctor lorem non justo. Nam lacus libero, pretium at, lobortis
  vitae, ultricies et, tellus. Donec aliquet, tortor sed accumsan bibendum,
  erat ligula aliquet magna, vitae ornare odio metus a mi. Morbi ac orci et
  nisl hendrerit mollis. Suspendisse ut massa. Cras nec ante. Pellentesque a
\end{filecontents}
\documentclass{article}
%--------------------
\usepackage[top=0.35in,bottom=0.35in,width=4in,landscape,includefoot,includehead]{geometry}
%--------------------
\usepackage{xcolor}
\usepackage{fancyhdr}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}
\lhead{Left}\rhead{Right}
\pagestyle{fancy}
%--------------------
\usepackage{multicol}
\setlength{\columnseprule}{0.4pt}
\setlength{\columnsep}{0.25in}
%--------------------
\usepackage{lipsum}

\usepackage{xparse}

\newlength\aetmpdima
\newlength\aetmpdimb
%% Loop to reduce the height to below max value
\def\whileloop#1#2%
  {\aetmpdima#1%
   \aetmpdimb#2%
   \ifdim\aetmpdima>\aetmpdimb\relax
      \aetmpdima\dimexpr\aetmpdima-\aetmpdimb\relax
      \whileloop\aetmpdima\aetmpdimb
   \fi
   #1\aetmpdima
  }

\newlength{\myenvWIDTH}
\newlength{\myenvHEIGHT}
\newlength{\myenvREMAINDER}
\newlength{\myenvSTRUT}
\newcommand{\myenvCOLCNT}{4}
\setlength{\myenvWIDTH}{10in}
\setlength{\myenvHEIGHT}{2.25in}
\setlength{\myenvSTRUT}{0pt}
\newsavebox{\singlecolumnbox}
\NewDocumentCommand{\aecols}{ m }
  {
    %% create a box the width of one column
    \begin{lrbox}{\singlecolumnbox}%
      \begin{minipage}{\dimexpr(\myenvWIDTH-\number\numexpr\myenvCOLCNT-1\relax\columnsep)/\myenvCOLCNT}
        \input{#1}%
      \end{minipage}%
    \end{lrbox}%
    %% reduce lengths to get lengths of the struts
    \setlength{\myenvREMAINDER}{\dimexpr\myenvCOLCNT\myenvHEIGHT-(\ht\singlecolumnbox+\dp\singlecolumnbox)\relax}%
    \ifdim\myenvREMAINDER>\myenvHEIGHT\relax
      \setlength{\myenvSTRUT}{\myenvHEIGHT}\fi          
    \whileloop{\myenvREMAINDER}{\myenvHEIGHT}%
    %% format the multicolumn environment
    \noindent
    \begin{minipage}[t][\myenvHEIGHT]{\myenvWIDTH}%
    \noindent
    \begin{multicols}{\myenvCOLCNT}%
        \raisebox{0pt}[0pt][0pt]{\textcolor{gray!60}{\rule[\dimexpr-\myenvHEIGHT+2ex]{4pt}{\myenvHEIGHT}}}
        \input{#1}
        \textcolor{blue}{\rule{4pt}{\dimexpr\myenvREMAINDER}}
        \textcolor{red}{\rule{4pt}{\dimexpr\myenvSTRUT}}
    \end{multicols}%
    \par\xdef\tpd{\the\prevdepth}
    \end{minipage}%
    \par\prevdepth\tpd
}

\begin{document}

\lipsum[1]
\vspace{2ex}

\noindent\hspace*{\dimexpr\textwidth/2-\myenvWIDTH/2}%
\rule{\myenvWIDTH}{5pt}

\noindent\hspace*{\dimexpr\textwidth/2-\myenvWIDTH/2}%
\aecols{content}

\vspace{2ex}
\lipsum[2]

\end{document}

在此处输入图片描述

第一个问题是我似乎无法正常\vspace工作。所以,我不得不使用\rule。在上面的例子中,我给出了不同于的宽度,0pt只是为了帮助它们在开发过程中可见。同样,开头的灰色支柱只是为了开发目的。

第二个问题,我有时会收到多个 overfullvbox错误:显然是由我的 struts 引起的,但仅限于某些参数值。(不过现在似乎无法重现它们。)当我收到错误时,错误数量远远超过我创建的 struts。抱歉,我现在无法重现它们。 :(

第三个问题,我无法让环境后的间距正确运行。我试过这个\prevdepth技巧,但在这里不起作用。

第四,问题不大,我通过从外部文件读取文本两次来解决必须重新格式化相同文本的问题。我可以忍受这一点,但如果我不必走这条路就好了。

关于如何解决此问题有什么建议吗?

附言

如果我能重新发现导致错误的参数值vbox,我会将它们发布在这个问题后面的评论中。

答案1

我将使用一种低级方法\vsplit

\documentclass{article}
\usepackage[latin]{babel} % to hyphenate lipsum
\usepackage{microtype}    % avoid overfull lines
%--------------------
\usepackage[
  top=0.35in,
  bottom=0.35in,
  width=4in,
  landscape,
  includefoot,
  includehead,
]{geometry}

%--------------------

\usepackage{fancyhdr}
\pagestyle{fancy}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}
\fancyhead[L]{Left}
\fancyhead[R]{Right}

%--------------------

\usepackage{lipsum}

\begin{document}

\lipsum[1]

\vspace{2ex}

\noindent
\hspace*{-3in}%
\makebox[0pt][l]{%
  \setbox0=\vbox{\hsize=2.5in
    \lipsum[1-2]
  }%
  \splittopskip=0pt \vbadness=10000
  \setbox2=\vsplit0 to 2.5in
  \vtop{\hrule height0pt\unvbox2}\hspace{0.25in}\vrule\hspace{0.25in}%
  \setbox2=\vsplit0 to 2.5in
  \vtop{\hrule height0pt\unvbox2}\hspace{0.25in}\vrule\hspace{0.25in}%
  \vtop{\hrule height0pt\unvbox0}
}

\vspace{3ex}

\lipsum[2]

\end{document}

随意调整定位。

在此处输入图片描述

答案2

好吧,开始吧。我对这个建议非常谨慎,这只是一个开始——如果合适,你会想根据自己的需要进行调整。不过,我思考这就是你想要的。我同意 egreg 的观点:\vsplit是你的朋友。先看代码:

    \documentclass{article}

%--------------------
\usepackage[top=0.35in,bottom=0.35in,width=4in,landscape,includefoot,includehead]{geometry}
%--------------------
\usepackage{fancyhdr}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}
\lhead{Left}\rhead{Right}
\pagestyle{fancy}

\usepackage{calc}
\usepackage{lipsum}

\newcommand{\breakit}{\vfill\eject\ \unskip}

\newlength{\unbalcolht}

\newenvironment{unbalminicols}[1][2in]{%
\setlength{\unbalcolht}{#1}
\parindent0pt
\vspace{2ex}
\hspace{-2.8in}
\begin{minipage}[1]{9.5in}
\setbox0=\vtop\bgroup\setlength{\hsize}{\linewidth/3-1em}%
}{%
\vfill
\egroup
\splittopskip0pt
\setbox1=\vtop{\vsplit0 to \unbalcolht}
\setbox2=\vtop{\vsplit0 to \unbalcolht}
\setbox3=\vtop{\vsplit0 to \unbalcolht}
\hbox to \linewidth{%
    \vrule\hfil
    \box1%
    \hfil\vrule\hfil
    \box2%
    \hfil\vrule\hfil
    \box3%
    \hfil\vrule
}
\end{minipage}
\vspace{2ex}
}

\begin{document}

\lipsum[1]

\begin{unbalminicols}[1in]
This is the first column\breakit
This is the second column\breakit
This is the third column
\end{unbalminicols}

\lipsum[5]


\end{document}

输出如下:

更正了 3 列输出。

环境unbalminicols负责完成这项工作。它需要一个可选参数来调整列的高度,默认值为 2 英寸。\breakit在必要时完成分列工作。如果您只有两列文本,则需要一个\breakit来填充小页面。

这里有很多纯 TeX,我确信有更好的方法来实现这一点。希望这能有所帮助。


由于匆忙,我假设有四列。我的错。我已将代码(和屏幕截图)更新为三列。还演示了可选参数:\begin{unbalminicols}[1in]

答案3

如果我理解正确的话,方法如下:

\documentclass[pagesize, DIV=calc, parskip=half]{scrartcl}
\usepackage{multicol, microtype, blindtext, lmodern}
\begin{document}
Here is text in one column.

\blindtext

\begin{addmargin}[-2cm]{-2cm}
  \begin{multicols}{3}
    \blindtext
  \end{multicols}
\end{addmargin}


\blindtext

\end{document}

如果您不使用 KOMA-script(您最好这样做!),那么您可以使用 scrextend 包获得 addmargin 环境。

在此处输入图片描述

答案4

受@egreg解决方案的启发,以下是他所建议的一个小概括。它需要以下软件包environ

\documentclass{article}
\usepackage[
    top=0.35in,
    bottom=0.35in,
    width=4in,
    landscape,
    includefoot,
    includehead,
  ]{geometry}
\usepackage{fancyhdr}
\pagestyle{fancy}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}
\fancyhead[L]{Left}
\fancyhead[R]{Right}
%--------------------

\usepackage{environ}
\usepackage{pgfkeys}
\makeatletter
\newlength{\ae@width}
\newlength{\ae@hoffset}
\newlength{\ae@topsep}
\newlength{\ae@botsep}
\newlength{\ae@colheight}
\newlength{\ae@colsep}
\newlength{\ae@colrulewidth}
\pgfkeys{/ae/multi/columns/.cd,
  width/.code=\setlength\ae@width{#1},
  hoffset/.code=\setlength\ae@hoffset{#1},
  topsep/.code=\setlength\ae@topsep{#1},
  botsep/.code=\setlength\ae@botsep{#1},
  height/.code=\setlength\ae@colheight{#1},
  colsep/.code=\setlength\ae@colsep{#1},
  colrulewidth/.code=\setlength\ae@colrulewidth{#1},
}

\NewEnviron{aemulticol}[1][]
  {\pgfkeys{/ae/multi/columns/.cd,
    topsep=2ex,
    botsep=2ex,
    hoffset=-3in,
    width=2in,
    height=4in,
    colsep=2em,
    colrulewidth=0.4pt,
    #1}%%
   \vspace{\ae@topsep}\par
   \noindent
   \hspace*{\ae@hoffset}%%
   \makebox[0pt][l]{\ae@set@multi@cols}%%
   \vspace{\ae@botsep}\par
  }

\def\ae@set@multi@cols{%%
  \setbox0=\vbox{%%
    \hsize=\ae@width
    \BODY}%%
  \splittopskip=0pt
  \vbadness=10000\relax
  \ae@build@column
}

\def\ae@build@column{%%
  \setbox2=\vsplit0 to \ae@colheight 
  \vtop{%%
    \hrule height0pt 
    \unvbox2
  }%%
  \ifvoid0\relax\else
    \hspace{\dimexpr(\ae@colsep-\ae@colrulewidth)/2}%%
    \vrule width \ae@colrulewidth
    \hspace{\dimexpr(\ae@colsep-\ae@colrulewidth)/2}%%
    \expandafter\ae@build@column
  \fi}  

\makeatother

\begin{document}

  Alice was beginning to get very tired of sitting by her sister on
  the bank, and of having nothing to do. Once or twice she had peeped
  into the book her sister was reading, but it had no pictures or
  conversations in it, ``and what is the use of a book,'' thought
  Alice, ``without pictures or conversations?''
\begin{aemulticol}[width=2.75in,height=4.00in]
  So she was considering in her own mind (as well as she could, for
  the day made her feel very sleepy and stupid), whether the pleasure
  of making a daisy-chain would be worth the trouble of getting up and
  picking the daisies, when suddenly a White Rabbit with pink eyes ran
  close by her.

  There was nothing so very remarkable in that, nor did Alice think it
  so very much out of the way to hear the Rabbit say to itself, ``Oh
  dear! Oh dear! I shall be too late!'' But when the Rabbit actually
  took a watch out of its waistcoat-pocket and looked at it and then
  hurried on, Alice started to her feet, for it flashed across her
  mind that she had never before seen a rabbit with either a
  waistcoat-pocket, or a watch to take out of it, and, burning with
  curiosity, she ran across the field after it and was just in time to
  see it pop down a large rabbit-hole, under the hedge. In another
  moment, down went Alice after it!

  The rabbit-hole went straight on like a tunnel for some way and then
  dipped suddenly down, so suddenly that Alice had not a moment to
  think about stopping herself before she found herself falling down
  what seemed to be a very deep well.

  Either the well was very deep, or she fell very slowly, for she had
  plenty of time, as she went down, to look about her. First, she
  tried to make out what she was coming to, but it was too dark to see
  anything; then she looked at the sides of the well and noticed that
  they were filled with cupboards and book-shelves; here and there she
  saw maps and pictures hung upon pegs. She took down a jar from one
  of the shelves as she passed. It was labeled ``ORANGE MARMALADE,''
  but, to her great disappointment, it was empty; she did not like to
  drop the jar, so managed to put it into one of the cupboards as she
  fell past it.

  Down, down, down! Would the fall never come to an end? There was
  nothing else to do, so Alice soon began talking to
  herself. ``Dinah'll miss me very much to-night, I should think!''
  (Dinah was the cat.) ``I hope they'll remember her saucer of milk at
  tea-time. Dinah, my dear, I wish you were down here with me!'' Alice
  felt that she was dozing off, when suddenly, thump! thump! down she
  came upon a heap of sticks and dry leaves, and the fall was over.

  Alice was not a bit hurt, and she jumped up in a moment. She looked
  up, but it was all dark overhead; before her was another long
  passage and the White Rabbit was still in sight, hurrying down
  it. There was not a moment to be lost. Away went Alice like the wind
  and was just in time to hear it say, as it turned a corner, ``Oh, my
  ears and whiskers, how late it's getting!'' She was close behind it
  when she turned the corner, but the Rabbit was no longer to be seen.
\end{aemulticol}
  She found herself in a long, low hall, which was lit up by a row of
  lamps hanging from the roof. There were doors all 'round the hall,
  but they were all locked; and when Alice had been all the way down
  one side and up the other, trying every door, she walked sadly down
  the middle, wondering how she was ever to get out again.

  Suddenly she came upon a little table, all made of solid
  glass. There was nothing on it but a tiny golden key, and Alice's
  first idea was that this might belong to one of the doors of the
  hall; but, alas! either the locks were too large, or the key was too
  small, but, at any rate, it would not open any of them. However, on
  the second time 'round, she came upon a low curtain she had not
  noticed before, and behind it was a little door about fifteen inches
  high. She tried the little golden key in the lock, and to her great
  delight, it fitted!

\end{document}

在此处输入图片描述

相关内容