1

As preamble, I specify I try to copy a specific behavior of NASA Graphics Standards Manual.

So I use multicol with tree columns inside in fixed hight minipage. But, I try to force mulcol to fill second and third column first, and to use the first column

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

And I get the following result Result of last code

So, the text of the lipsum began in the first column while the wool height of the second column are not filled. So I not exactly want to do \columnbreak because the goal is to use first column when the second and third once are completely filled.

In other words, I just want to “compress” text into last column.

I use a lot of ways to do this kind of \colfill. I try \vfill\null, \null\vfill\null, \vfill\eject, \vfill\break, but each time the first column is used before the second one is filled, or the first column is never used.

So how to force multicol to use the second columns as long as there is empty places on their bottom and let the main text as far as possible from the title section?

2

I took a look at the NASA document you indicated. I solved a similar problem through the use of \eject which is not often needed in LaTeX code. To make a point, I used text from page 5.10 of the publication, though I did not match the fonts -- that can easily be done with fontspec.sty. The match is surprisingly close.

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

In taking another, closer look at the NASA graphics guidlines, I think that they are balancing as much text as there is rather than to a predetermined height, the amount of text being managed accordingly.

More possibilities

There are two ways to approach this. First, you can decide when text should flow into the first column. I use xparse.sty to create an environment that takes an optional * -- using it allows text to flow into the first column. Frankly, I prefer this as it leaves control of this in the user's hands.

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

enter image description here

Alternatively, you can let TeX make the decision based on a target height that you can specify. Notice that the text is now an argument to the environment:

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

enter image description here

One more...

This uses environ.sty and, again, lets TeX decide when to fill the first column:

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

The output is identically the same as the third example above:

enter image description here

One more

This takes advantage of the b argument type from xparse. Please see commented code for more info.

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

enter image description here

| improve this answer | |
  • But the code you give doesn’t resolve the main problem: If the text is too long for the columns 2 and 3, your code didn’t try to put the text in the first column. Take a look to page 1.6, the text is too long, so the columns are used without increasing the minipage height. – fauve Apr 26 at 23:44
  • I've added a couple of alternatives. – sgmoye Apr 27 at 11:55
  • And another possibility... – sgmoye Apr 27 at 17:51
  • This is the last one... – sgmoye Apr 28 at 13:49
  • The answers are interesting but the second problem still: if their is too less text, the mdframed box didn’t keep the minimal height. As example, with \lipsum[4] the mdframed is resized under the asked minimal height size. It’s good to resize the box to increase height when their is too much text, but the box should not go under the asked minimal size. – fauve May 1 at 6:18
0

I think the reason why your \vfill appeared to be ignored is that in order to balance columns, multicols measures the natural height of the whole contents, and the natural height of a \vfill is zero... I believe what follows is more or less what you want. The number of columns is the optional argument of the symbolitem environment; it defaults to 3.

We first typeset the text in a minipage with appropriate width computed using the current values of \linewidth, \columnsep, \columnseprule and the desired number of columns. We measure the height of this box, then compute the “missing height” for the first column by substracting the result from (desired height)×(number of columns). Finally, we typeset the text inside multicols (no outer minipage needed) with an inserted glob of vertical glue having the computed height plus small amounts of stretchability and shrinkability to make sure multicols will be able to fill everything nicely.

I commented out the \newpage in order to show two examples with different numbers of columns on the same page. You can of course uncomment it, but don't add \noindent between this \newpage and the following \begin{mdframed}, as this would start a new paragraph before the mdframed environment!

Unfortunately, in some cases, you'll need to adjust the height a little bit because the desired height is not “feasible” (maybe my computation is missing something?). As a consequence, heights such as 0.2\textheight in the second mandatory argument of symbolitem are probably not a great idea, because they depend on the top and bottom margins. I'd favor font-dependent lengths such as 35ex (even then, the \linewidth counts, therefore also the left and right margins).

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

enter image description here

The same with tcolorbox instead of 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}

enter image description here

| improve this answer | |

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.