作为序言,我指定我尝试复制特定行为NASA 图形标准手册。
因此,我使用multicol
固定高度的三列minipage
。但是,我尝试强制 mulcol 先填充第二列和第三列,然后使用第一列
\documentclass{article}
\usepackage{multicol}
\usepackage{geometry} % Used only to enlarge page in this example
\usepackage{lipsum}
\usepackage{mdframed} % Used only to highlight the minipage environment.
\usepackage{xcolor} % Used to set color for minpage background highlight
\geometry{left=1cm, right=1cm, top=2cm, bottom=1cm}
\newenvironment{symbolitem}[1]
{
\newpage
\noindent\begin{mdframed}[backgroundcolor=lightgray]\begin{minipage}[t][0.25\textheight][t]{\textwidth}
\begin{multicols*}{3}
\textbf{#1} % Section title
\null\vfill
}
{
\end{multicols*}
\end{minipage}\end{mdframed}
}
\begin{document}
\begin{symbolitem}{Item title}
\lipsum[4]
\end{symbolitem}
\end{document}
因此,lipsum 的文本从第一列开始,而第二列的羊毛高度未填充。所以我并不完全想这样做,\columnbreak
因为目标是在第二列和第三列完全填充时使用第一列。
换句话说,我只想将文本“压缩”到最后一列。
我使用了很多方法来做这种事情\colfill
。我尝试了,,,,,但\vfill\null
每次都是在第二列填充之前使用第一列,或者从不使用第一列。\null\vfill\null
\vfill\eject
\vfill\break
那么,只要第二列底部有空白处,如何强制multicol
使用第二列,并让正文尽可能远离标题部分?
答案1
我查看了您指出的 NASA 文档。我通过使用\eject
LaTeX 代码中通常不需要的 解决了类似的问题。为了说明这一点,我使用了出版物第 5.10 页中的文本,尽管我没有匹配字体——这可以轻松完成fontspec.sty
。匹配非常接近。
\documentclass{article}
\usepackage{multicol}
\usepackage{geometry} % Used only to enlarge page in this example
\usepackage{lipsum}
\usepackage{mdframed} % Used only to highlight the minipage environment.
\usepackage{xcolor} % Used to set color for minpage background highlight
\geometry{left=1cm, right=1cm, top=2cm, bottom=1cm}
\newenvironment{symbolitem}[1]
{%
\begin{mdframed}[backgroundcolor=lightgray]
\begin{minipage}{\textwidth}
\begin{multicols}{3}
\parbox{\linewidth}{\bfseries\sffamily#1}
\eject
\sffamily
\parskip1ex
\raggedright
}{
\end{multicols}
\end{minipage}
\end{mdframed}
}
\raggedcolumns
\begin{document}
\begin{symbolitem}{Cover Design:\\Quality Publications }
Covers in this category are dramatic
and appealing. The main purpose
of the cover is to attract the reader and
serve as an effective preview of what
is to follow. It is, in one sense, a packaging problem and both front and
back covers should be considered
part of the package.
Concepts play an important role in
quality publications and should be explored thoroughly. Special attention
must be paid to the quality of the photograph or illustration as well as
the content. Superior quality will help
distinguish the cover from other
competitive publications.
4/color process printing is desirable,
wherever possible, to contribute to the
general effect and prestige of the
publication. While it is impossible to
show our demonstrations in color,
all of the covers below were designed
in 4/color process.
Note that space has been used to
separate the mission patch from the
NASA logotype and signature.
\end{symbolitem}
\end{document}
再次仔细观察 NASA 的图形指导方针,我认为他们正在平衡尽可能多的文本,而不是预先确定的高度,并相应地管理文本的数量。
更多可能性
有两种方法可以解决这个问题。首先,您可以决定文本何时流入第一列。我习惯xparse.sty
创建一个带有可选项的环境*
- 使用它可以让文本流入第一列。坦率地说,我更喜欢这种方法,因为它将控制权交给了用户。
\documentclass{article}
\usepackage{multicol}
\usepackage{geometry} % Used only to enlarge page in this example
\usepackage{lipsum}
\usepackage{mdframed} % Used only to highlight the minipage environment.
\usepackage{xcolor} % Used to set color for minpage background highlight
\usepackage{xparse}
\newlength{\colswd}
\geometry{left=1cm, right=1cm, top=2cm, bottom=1cm}
%% In case you need to break a column anywhere even inside a paragraph:
\def\mycolumnbreak{\ifhmode\endgraf\columnbreak\else\columnbreak\fi}
\NewDocumentEnvironment{symbolitem}{sm} %% *=text in first column; #2=title
{%
\begin{mdframed}[backgroundcolor=lightgray]
\begin{minipage}{\textwidth}
\begin{multicols}{3}
\parbox{\linewidth}{\bfseries\sffamily#2}
\IfBooleanTF{#1}{\par\smallskip}{\eject} %% <<<<----
\sffamily
\parskip1ex
\raggedright
}{
\end{multicols}%
\end{minipage}%
\end{mdframed}%
}
\raggedcolumns
\begin{document}
\begin{symbolitem}{Cover Design:\\Quality Publications }
Covers in this category are dramatic
and appealing. The main purpose
of the cover is to attract the reader and
serve as an effective preview of what
is to follow. It is, in one sense, a packaging problem and both front and
back covers should be considered
part of the package.
Concepts play an important role in
quality publications and should be explored thoroughly. Special attention
must be paid to the quality of the photograph or illustration as well as
the content. Superior quality will help
distinguish the cover from other
competitive publications.
4/color process printing is desirable,
wherever possible, to contribute to the
general effect and prestige of the
publication. While it is impossible to
show our demonstrations in color,
all of the covers below were designed
in 4/color process.
Note that space has been used to
separate the mission patch from the
NASA logotype and signature.
\end{symbolitem}
\begin{symbolitem}*{Cover Design:\\Quality Publications }%% notice *
Covers in this category are dramatic
and appealing. The main purpose
of the cover is to attract the reader and
serve as an effective preview of what
is to follow. \mycolumnbreak It is, in one sense, a packaging problem and both front and
back covers should be considered
part of the package.
Concepts play an important role in
quality publications and should be explored thoroughly. Special attention
must be paid to the quality of the photograph or illustration as well as
the content. Superior quality will help
distinguish the cover from other
competitive publications.
4/color process printing is desirable,
wherever possible, to contribute to the
general effect and prestige of the
publication. While it is impossible to
show our demonstrations in color,
all of the covers below were designed
in 4/color process.
Note that space has been used to
separate the mission patch from the
NASA logotype and signature.
\end{symbolitem}
\begin{symbolitem}*{Agency and Center Identification}% Notice *
\lipsum[2][1-2]
\mycolumnbreak
\lipsum[1][1-5]
\mycolumnbreak
\lipsum[3][2-5]
\end{symbolitem}
\end{document}
或者,您可以让 TeX 根据您指定的目标高度做出决定。请注意,文本现在是争论对环境:
\documentclass{article}
\usepackage{multicol}
\usepackage{geometry} % Used only to enlarge page in this example
\usepackage{lipsum}
\usepackage{mdframed} % Used only to highlight the minipage environment.
\usepackage{xcolor} % Used to set color for minpage background highlight
\usepackage{xparse}
\newlength{\colswd}
\newlength{\targetht}
\geometry{left=1cm, right=1cm, top=2cm, bottom=1cm}
%% #1 Optional target height of text; #2 Title text; #3 Text
\NewDocumentEnvironment{symbolitem}{O{0.25\textheight}+m+m}{% %% *=text in first column; #2=title%
\setlength{\targetht}{#1}%
\setlength{\colswd}{\dimexpr 0.333\textwidth- 0.5\columnsep\relax}%
\setbox0=\vbox{\hsize\colswd#3}%
\begin{mdframed}[backgroundcolor=lightgray]
\begin{multicols}{3}
\noindent\textsf{\textbf{#2}}\par
% if short, two columns; if longer 3 columns
\ifdim\ht0<2\targetht\columnbreak\else\medskip\fi
%% Added these penalties automatically to prevent widows and clubs
\widowpenalty10000
\clubpenalty10000
#3
}{%
\end{multicols}
\end{mdframed}
}
\setlength{\multicolsep}{0pt}
\begin{document}
\begin{symbolitem}{Lorem Ipsum:\\In Two Columns}
{\lipsum[1]}
\end{symbolitem}
\begin{symbolitem}{Lorem Ipsum:\\In Three Columns}
{\lipsum[1-2]}
\end{symbolitem}
%% Notice change in optional height specification:
\begin{symbolitem}[0.5\textheight]{Lorem Ipsum:\\In Two Columns Again}
{\lipsum[1-2]}
\end{symbolitem}
\end{document}
多一个...
这再次使用environ.sty
并让 TeX 决定何时填充第一列:
\documentclass{article}
\usepackage{multicol}
\usepackage{geometry} % Used only to enlarge page in this example
\usepackage{lipsum}
\usepackage{mdframed} % Used only to highlight the minipage environment.
\usepackage{xcolor} % Used to set color for minpage background highlight
\usepackage{xparse}
\usepackage{environ}
\newlength{\colswd}
\newlength{\targetht}
\geometry{left=1cm, right=1cm, top=2cm, bottom=1cm}
%% #1 Optional target height of text; #2 Title text; #3 Text
\NewEnviron{symbolitem}[2][0.25\textheight]{
\setlength{\targetht}{#1}
\setlength{\colswd}{\dimexpr\textwidth/3-2\columnsep\relax}
\setbox0=\vbox{\hsize=\colswd\noindent\textsf{\textbf{#2}\endgraf}\BODY}
\begin{mdframed}[backgroundcolor=lightgray]
\begin{multicols}{3}
\noindent\textsf{\textbf{#2}\endgraf}
\ifdim\ht0>2\targetht \medskip \else \columnbreak\fi
\widowpenalty10000
\clubpenalty10000
\BODY
\end{multicols}
\end{mdframed}
}
%% This prevents unwanted space above the columns
\setlength{\multicolsep}{0pt}
\begin{document}
\begin{symbolitem}{Lorem Ipsum:\\In Two Columns}
{\lipsum[1]}
\end{symbolitem}
\begin{symbolitem}{Lorem Ipsum:\\In Three Columns}
{\lipsum[1-2]}
\end{symbolitem}
%% Notice change in optional height specification:
\begin{symbolitem}[0.5\textheight]{Lorem Ipsum:\\In Two Columns Again}
{\lipsum[1-2]}
\end{symbolitem}
\end{document}
输出与上面第三个示例完全相同:
多一个
这利用了 的b
参数类型xparse
。请参阅注释代码以获取更多信息。
\documentclass{article}
\usepackage{multicol}
\usepackage{lipsum}
\usepackage{xparse}
\usepackage{keyval}
\newlength{\colswd}
\newlength{\targetht}
\newif\iffillfirst
%% Defaults, adjust to suit:
\def\numofcols{3}
\setlength{\targetht}{0.25\textheight}
%% For keyval.sty
\makeatletter
\define@key{mcefc}{targetht}{\setlength{\targetht}{#1}}
\define@key{mcefc}{fillfirst}[true]{\csname fillfirst#1\endcsname}
\define@key{mcefc}{numofcols}{\def\numofcols{#1}}
\makeatother
%% #1 Optional for keyval; #2 Title; #3 Text body, note use of +b argument
%% There are 3 keyval options:
%% targetht -- the default is 0.25\textheight; set, e.g., using 'targetht=0.3\textheight'
%% fillfirst -- this forces text in the first column; use either 'fillfirst' or 'fillfirst=true'
%% default is 'false'.
%% numofcols -- the number of columns, default is 3; set using 'numofcols=4'
\NewDocumentEnvironment{symbolitem}{O{}m+b}{%
\overfullrule3pt
\raggedright
\setkeys{mcefc}{#1}%
\setlength{\colswd}{\dimexpr\textwidth/\numofcols-2\columnsep\relax}%
%% Find approximate height of text:
\setbox0=\vbox{\hsize\colswd\textsf{\textbf{#2}}\par]#3}%
\begin{multicols}{\numofcols}
\noindent\textsf{\textbf{#2}\endgraf}
\iffillfirst %% Force fill first column
\smallskip
\else %% Test height of text
\ifdim\dimexpr\ht0/\numofcols\relax>\targetht %% Too high, fill first column
\smallskip
\else %% Not too high, don't fill first column
\columnbreak
\fi
\fi
%% Prevents lonely lines at the ends and beginnings of columns
\widowpenalty10000
\clubpenalty10000
#3
\end{multicols}%
}{\bigskip}
\setlength{\multicolsep}{0pt}
\begin{document}
\begin{symbolitem}[]{Lorem Ipsum:\\In Two of Three Columns}
\lipsum[1][1-4]
\end{symbolitem}
\begin{symbolitem}[]{Lorem Ipsum:\\In Three Columns}
\lipsum[1][1-13]
\end{symbolitem}
\begin{symbolitem}[numofcols=4]{Lorem Ipsum:\\In Three of Four Columns}
\lipsum[1][2-7]
\end{symbolitem}
\begin{symbolitem}[fillfirst,numofcols=4]{Lorem Ipsum:\\In Four of Four Columns}
\lipsum[1][2-6]
\end{symbolitem}
\end{document}
答案2
我认为您的内容被忽略的原因\vfill
在于,为了平衡列,multicols
测量整个内容的自然高度,而 a 的自然高度\vfill
为零... 我相信接下来的内容或多或少就是您想要的。列数是环境的可选参数symbolitem
;默认为 3。
我们首先在 中排版文本,并使用 、 的当前值和所需的列数minipage
计算适当的宽度。我们测量此框的高度,然后通过从\linewidth
(所需高度)×(列数) 中减去结果来计算第一列的“缺失高度”。最后,我们在内部(不需要外部)排版文本,插入一个垂直粘连块,该粘连块具有计算出的高度以及少量的可拉伸性和可收缩性,以确保能够很好地填充所有内容。\columnsep
\columnseprule
multicols
minipage
multicols
我注释掉了 ,\newpage
以便在同一页上显示两个具有不同列数的示例。当然,您可以取消注释它,但不要\noindent
在它\newpage
和下面的之间添加\begin{mdframed}
,因为这会在mdframed
环境之前开始一个新段落!
不幸的是,在某些情况下,您需要稍微调整高度,因为所需的高度不“可行”(也许我的计算遗漏了什么?)。因此,像0.2\textheight
第二个强制参数中的高度symbolitem
可能不是一个好主意,因为它们取决于顶部和底部边距。我更喜欢字体相关的长度,例如35ex
(即使这样,\linewidth
计数也是如此,因此左右边距也是如此)。
\documentclass{article}
\usepackage{geometry} % Used only to enlarge page in this example
\geometry{left=1cm, right=1cm, top=2cm, bottom=2cm}
\usepackage{multicol}
\usepackage{environ}
\usepackage{mdframed} % Used only to highlight the minipage environment.
\usepackage{xcolor} % Used to set color for minipage background highlight
\usepackage{lipsum}
\makeatletter
\newdimen\mydim
\newdimen\spacetofill
\newsavebox{\mybox}
\NewEnviron{symbolitem}[3][2]
{%
% \newpage % commented out for the demo. Don't add \noindent afterwards,
% as this would start a new paragraph before the mdframed environment!
\begin{mdframed}[backgroundcolor=lightgray]%
\mydim=\dimexpr
(\linewidth - (\columnsep+\columnseprule)*(#1-1))/(#1) \relax
\begin{lrbox}{\mybox}
\begin{minipage}{\mydim}
\textbf{#2}\par\BODY
\end{minipage}%
\end{lrbox}%
\spacetofill=\dimexpr \dimexpr #3\relax*(#1) - \ht\mybox \relax
\begin{multicols}{#1}
\textbf{#2}\par\nobreak\vspace{\spacetofill plus 1ex minus 1ex}%
\@afterheading
\BODY
\end{multicols}%
\end{mdframed}%
}
\makeatother
\begin{document}
\begin{symbolitem}[3]{Item title}{35ex}
\lipsum[1-3]
\end{symbolitem}
\begin{symbolitem}[4]{Item title}{0.19\textheight}
\lipsum[1-3]
\end{symbolitem}
\end{document}
同理,tcolorbox
改为mdframed
:
\documentclass{article}
\usepackage{geometry} % Used only to enlarge page in this example
\geometry{left=1cm, right=1cm, top=2cm, bottom=2cm}
\usepackage{multicol}
\usepackage{environ}
\usepackage{tcolorbox}% Used only to highlight the minipage environment.
\usepackage{xcolor} % Used to set color for minipage background highlight
\usepackage{lipsum}
\makeatletter
\newdimen\mydim
\newdimen\spacetofill
\newsavebox{\mybox}
\NewEnviron{symbolitem}[3][2]
{%
% \newpage % commented out for the demo. Don't add \noindent afterwards,
% as this would start a new paragraph before the tcolorbox environment!
\begin{tcolorbox}[arc=0pt, colback=lightgray]%
\mydim=\dimexpr
(\linewidth - (\columnsep+\columnseprule)*(#1-1))/(#1) \relax
\begin{lrbox}{\mybox}
\begin{minipage}{\mydim}
\textbf{#2}\par\BODY
\end{minipage}%
\end{lrbox}%
\spacetofill=\dimexpr \dimexpr #3\relax*(#1) - \ht\mybox \relax
\begin{multicols}{#1}
\textbf{#2}\par\nobreak\vspace{\spacetofill plus 1ex minus 1ex}%
\@afterheading
\BODY
\end{multicols}%
\end{tcolorbox}%
}
\makeatother
\begin{document}
\begin{symbolitem}[3]{Item title}{31ex}
\lipsum[1-3]
\end{symbolitem}
\begin{symbolitem}[4]{Item title}{0.22\textheight}
\lipsum[1-3]
\end{symbolitem}
\end{document}