6

Background

Trying to determine whether a column break must be inserted on a two-column page. There are multiple sections on the page. Before the last section on the page, I want to insert a column break, but only if within the first column and only if there is sufficient space in the second column (i.e., without forcing a page break).

Problem

The following code illustrates the problem:

\starttext
    \startcolumns[n=2, balance=no]
    \startsection[title=Section1]
    \input knuth
    \stopsection
    \startsection[title=Section2]
    \input zapf
    \stopsection
    \column
    \startsection[title=Section3]
    \input knuth
    \stopsection

    \stopcolumns
\stoptext

The \column break should not be applied because section 3 is in the second column, which causes an undesired page break. To clarify, the condition to determine whether or not to break the column should be independent of the text itself. For example, something like:

\setuphead[chapter][
  before={\startcolumns[n=2, balance=no,]},
  after={\stopcolumns},
]

% If the section is the last section in the chapter
% *and* the section is not in the last column *and*
% inserting a column break does not cause pagination...
\setuphead[section][
  before={%
    \if_last_section{%
      \if_not_last_column{%
        \if_fits_in_last_column_without_pagination{\columnbreak}
      }
    }
  },
]

\starttext
  \startchapter
    \startsection[title=Section1]
    \input knuth
    \stopsection
    \startsection[title=Section2]
    \input zapf
    \stopsection
    \startsection[title=Section3]
    \input knuth
    \stopsection
  \stopchapter
\stoptext

Question

How do you force ConTeXt to insert a column break if a section is in the first column, but not if the section is in the second column?

Related

Very similar question for LaTeX:

Using LaTeX, the following code -- part of the document class -- helped dynamically determine whether or not a column break should be present:

\def\columnbreakunlesslast{%
  \docolaction{\typeout{in first column}\inlastfalse}%
              {\typeout{in middle column}\inlasttrue}%
              {\typeout{in last column}\inlasttrue}%
  \unless \ifinlast \columnbreak \fi
}

This allowed documents to be written such that manually inserting column breaks was not necessary.

Dave Jarvis
  • 11,809
  • \page and \page[disable] will accomplish it (of course, wherever you wish to force the page break). Either way, irrespective whether \column is applied. – doed Oct 08 '13 at 07:16
  • @doed: See this answer: http://tex.stackexchange.com/a/122474/2148 -- it uses \docolaction{\typeout{in first column} to determine whether the text is still in the first column. I'm looking for something like that. – Dave Jarvis Oct 08 '13 at 18:14
  • The content is user-generated. I don't necessarily know where the "last section" will be within the document. – Dave Jarvis Oct 08 '13 at 19:48
  • Yes Dave. I realized that. great question though. – doed Oct 08 '13 at 19:50
  • I'm wondering not only if that answer it's useful enough to deserve a vote. I can care less about the bounty points. Since the question expired for one, and secondly because I'd just like to know what would someone who is actively involved with ConTeXt would do. It would be good to find out what Hagen himself would do in this case. – doed Oct 16 '13 at 11:22
  • @doed: My software generates books automatically using user-generated content (as per the related question); a manual solution will not work. – Dave Jarvis Oct 16 '13 at 15:29
  • At no point mccolaction may be deployed with user-generated content. Leave out that \columnbreakunlesslast in LaTeX and see what happens. For that matter Here is with \columnbreak instead, which accomplishes the same thing. – doed Oct 17 '13 at 12:24
  • Even with the mccolaction dated 7/7/2013, the \columnbreakunlesslast must be tweaked manually, or else it won't work. – doed Oct 17 '13 at 12:54
  • @doed: The columnbreakunlesslast was tweaked (as shown in the question), but it was tweaked in the document class file, not within any document. – Dave Jarvis Oct 17 '13 at 16:15
  • How is it that the code of mccolaction allowed documents not to have a \columnbreakunlesslast? For the sake of clarity, unless you include \columnbreakunlesslast in the document, whether 'user-generated' or not, it won't break the columns as originally intended. – doed Oct 18 '13 at 11:13
  • I find it distastefully fallacious to prove a point at the expense or the lack thereof, of a feature (more and more code) of an unrelated system, in this case LaTeX, for this question for one, was geared toward ConTeXt, but you seemed more biased of Mittlebach's answer, since you accepted it as absolute and final, even though, in this respect, you could probably go farther with ConTeXt. Did you know that ConTeXt stretches and shrinks more than LaTeX? No pun intended. – doed Oct 18 '13 at 11:13
  • When you posted the question, I was unsure what you wanted to accomplish, and to make matters worse, I hadn't even paid attention to the package mccolaction, until after you linked the similarly related LaTeX question. But upon closer look , you can try this out in ConTeXt. For example, \vfil\unpenalty\vbox \input bla bla bla, with the addition of say, \columnbreak or a \vfilll, and see how it becomes easily stretchable and shrinkable. In LaTeX for example, let \lipsum substitute \input. And as you can see, as of this writing, this is unlikely attainable in LaTeX. – doed Oct 18 '13 at 11:15
  • @doed: I am looking for a solution (in ConTeXt) that does not intermingle presentation with content. This means that the \columbreak must be conditionally applied outside of \starttext. I have clarified the intent with an example. – Dave Jarvis Oct 18 '13 at 16:34

1 Answers1

5

I will try to keep it simple. You have two options, the first one:


\columnbreak

The second option is to apply some glue with \vfil, it all depends the amount of stretchability or shrinkability, for more glue apply \vfill or \vfilll to the box. Make a vertical box with either \vtop or \vbox. The latter is recommended, for the simple fact that it could be stretched and shrink and stretched and shrink some more with \columnbreak or \vfill. Did I say that ConTeXt can expand more than LaTeX?

So in ConTeXt the code would look as follows:


\vfil
\vbox{%
\input tufte
}

\vfil
\vbox{%
\input knuth\columnbreak % or \vfill
}

Consider this for example.


\starttext

\setuppagenumbering[state=stop]
    \startcolumns[n=3, balance=no]

    \section[1]

\input knuth

\section[2]

    \input zapf

    \section[3]

\vfil
\vbox{%
\input knuth 

}

\stopcolumns

\stoptext 

enter image description here

Or better yet, this one.



\def\doed\par{%
\vfil
\vbox{%
\input tufte
}}

\starttext

\hyphenation{wh-e-at}
\hyphenation{me-r-ge}
\hyphenation{st-r-ong-ly}
\setuppagenumbering[state=stop]
    \startcolumns[n=3, balance=no]

\section[1]

\input knuth

\section[2]

\input zapf

\section[3]

\doed  %The first break is applied. 

\input zapf

\section[4]

\doed %The second one follows. 

\input zapf
\input knuth
    \stopcolumns
\stoptext

enter image description here enter image description here

Or column break after first column



\def\doed\par{%
\vfil
\vbox{%
\input tufte
}}


\starttext

\hyphenation{wh-e-at}
\hyphenation{me-r-ge}
\hyphenation{st-r-ong-ly}
\setuppagenumbering[state=stop]
    \startcolumns[n=3, balance=no]

\section[1]

\input knuth

\section[2]

\doed 

\dorecurse{3}{\input zapf}

\section[3]

\doed

\input zapf

\input zapf

\section[4]

\doed

\input zapf

\input zapf

\section[5]

\doed

\input knuth

    \stopcolumns
\stoptext

enter image description here

enter image description here

And here is with \columnbreak which accomplishes the same thing than \columnbreakunlesslast from LaTeX




\starttext

\setuppagenumbering[state=stop]
    \startcolumns[n=3, balance=no]

\section[1]

\input knuth

\columnbreak

\section[2]

\dorecurse{2}{\input zapf}

    \section[3]

\input tufte

\stopcolumns

\stoptext 

enter image description here

doed
  • 938
  • 1
    Does ConTeXt change the meaning of \vfill and \unpenalty? If it doesn't, \vfill\unpenalty is completely equivalent to \vfill, as there is no penalty \unpenalty can act on. – egreg Oct 18 '13 at 12:43
  • Indeed! Although equivalent is not doing a thing. It's the same as adding a \unskip when no \medskip is present. I'll edit it. – doed Oct 18 '13 at 13:52