Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

On this site, a solution for text wrapping based on descriptions in Pandoc-generated ConTeXt documents was previously formulated. Although satisfactory for a one-page minimum working example, the then proposed solution still contains a pair of pitfalls.

One problem is that figure floats with text wrapping near a page break will misbehave as depicted below.

output1

\setuppapersize [A4][A4]
\setuplayout    [width=middle,  backspace=1.5in, cutspace=1.5in,
                 height=middle, topspace=0.75in, bottomspace=0.75in]

\setuppagenumbering[location={footer,center}]

\setuptolerance[horizontal, tolerant, stretch]

\setupexternalfigures [location=default]

% Keep old definitions
\let\oldplacefigure\placefigure
\let\oldexternalfigure\externalfigure

% For full text-width figures
\def\placefigure[#1]#2#3{%
  \def\externalfigure[##1]{\oldexternalfigure[##1][wfactor=fit]}%
  \oldplacefigure[#1]{#2}{#3}%
  \let\externalfigure\oldexternalfigure% Reset for in-line figures
  }

% For figures with wrapped text
\definedescription[description][
  headstyle=bold,
  style=normal,
  location=hanging,
  width=4cm
  ]

\def\startdescription#1{%
  \def\externalfigure[##1]{\oldexternalfigure[##1][width=4cm]}%
  \oldplacefigure[left,high,none]{}{#1}%
  \let\externalfigure\oldexternalfigure% Reset for in-line figures
  }
\def\stopdescription{\endgraf}

\starttext
\input douglas.tex

\input linden.tex

\input linden.tex

\section{Section near page end}

\startdescription{{\externalfigure[cow]}}
  \input linden.tex
\stopdescription

\input bryson.tex

Additional unit tests:

Yeah, but I produce milk! \externalfigure[cow][height=31pt]

\placefigure[here,nonumber]{Large milk cow}{\externalfigure[cow]}
\stoptext

Question

How can this problem be solved without changing anything between \starttext and \stoptext? (Remember, the whole idea is about fully automated document generation starting from Pandoc MarkDown.)

As an absolute ConTeXt-novice, I would think that perhaps something with penalties would be possible or I would hope for similar functionality as offered by the needspace LaTeX package.

Edit

I also tried the relatively new \starthanging[left]{#1} environment, with and without the [n=...] argument (the latter in the assumption that an image height could be measured in text line units). The results using \starthanging are equally unsatisfactory (see below);

  • The cow image is placed partly in the bottom margin,
  • The text continues being wrapped on the next page, and
  • (Not shown) When the wrapped text is short, the next paragraph will not be wrapped and overlap with the image.

Hence, a solution using \placefigure as outlined earlier looks more promising.

output3

share|improve this question
    
This is just how TEX works. Paragraph shaping is done before page breaking. What is the desired output in the second case? Page break before the description? I would also suggest posting this question on the context mailing list –  Aditya Sep 14 '13 at 16:11
    
The problem is acknowledged on the ConTeXt wiki. "This does not work correctly at a page boundary." –  Serge Stroobandt Sep 14 '13 at 19:55
    
You have to choose between the two evils. Large empty space on page, vs bad page break in a paragraph. –  Aditya Sep 14 '13 at 20:11
    
@Aditya The desired output in the second case would be a page break before the section title. –  Serge Stroobandt Sep 14 '13 at 20:23
    
@Aditya Is it not be possible to measure the remaining vertical space on a page and automatically decide for a page break or not before even starting the float with wrapping? –  Serge Stroobandt Sep 14 '13 at 20:27

1 Answer 1

up vote 5 down vote accepted

Here is a solution that checks if the figure will fit on a page; if not, it inserts a pagebreak. Note that this will result in ugly page breaks (but then the only way to avoid this is to rewrite the text). While I was at it, I also removed the overwrite of in-built ConTeXt macros and used the available hooks to change the figure dimensions.

\setuppapersize [A4][A4]
\setuplayout    [width=middle,  backspace=1.5in, cutspace=1.5in,
                 height=middle, topspace=0.75in, bottomspace=0.75in]

\setuppagenumbering[location={footer,center}]

\setuptolerance[horizontal, tolerant, stretch]

% Set inter-paragraph spacing
%\setupwhitespace[medium]% TOGGLE ON/OFF

\setupexternalfigures [location=default]

\startsetups placefigure
  \setupexternalfigure
    [wfactor=fit]
\stopsetups

% Floats do no have a before or a setup key
\appendtoks \setups{placefigure} \to \everyinsidefloat

\definemeasure[pageheight][\dimexpr(\pagegoal-\pagetotal-2\lineheight)]

\define[1]\startdescription
  {%\everyinsidefloat\emptytoks
   \setbox\scratchbox\vbox{\setupexternalfigure[width=4cm]#1}%
   \ifdim\ht\scratchbox>\dimexpr\measure{pageheight}\relax
      \page
   \fi
   \startplacefigure[location={left,high,none}]
     \box\scratchbox
   \stopplacefigure}

\define\stopdescription{\endgraf}

\starttext
\input douglas.tex

\input linden.tex

\input linden.tex

\section{Section near page end}

\startdescription{{\externalfigure[cow]}}
  \input linden.tex
\stopdescription

\input bryson.tex

Additional unit tests:

Yeah, but I produce milk! \externalfigure[cow][height=31pt]

\placefigure[here,nonumber]{Large milk cow}{\externalfigure[cow]}
\stoptext

enter image description here

share|improve this answer
    
I am truly impressed and still trying to get to grips with your code! I do not want to sound greedy, but now that you are at it, is there a way to also get the section title automatically on the next page? Thanks. –  Serge Stroobandt Sep 14 '13 at 21:33
    
You really should consider sending this code upstream to the ConTeXt developers so that more people can profit from this. –  Serge Stroobandt Sep 14 '13 at 21:35
    
@SergeStroobandt: I'll look into the starthanging code and see if there is a clean way to integrate this idea. As for automatic breaking of the section, I really don't know how to do that. When the section is being placed, TeX does not know what comes ahead. I don't understand the penalty mechanism to know if it is possible to tell TeX "If the figure does not fit on a page, break the page before a figure; but if the previous paragraph was a section, break the page before the previous paragraph". It may be possible using a two-pass method, but better ask on the mailing list. –  Aditya Sep 14 '13 at 21:52
    
Concerning the section title, I think you could use a similar vertical page measure as before. Then, if the remainder of the available page space is less than say four lines (excluding the section title), introduce a page break; if not, place the section title and continue. –  Serge Stroobandt Sep 14 '13 at 22:14
3  
If you know the height of the image, you can use \setuphead[section][before={\testpage[6]}]. This checks if there is enough space for 6 lines, if not, it places a pagebreak. –  Aditya Sep 14 '13 at 23:14

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.