6

Background

Looking to achieve a fairly complex layout from a Markdown source document. The layout resembles:

image layout

Code

\usemodule[newcolumnsets,visual]

\setuphead[chapter][
  header=empty,
  footer=empty,
  number=no,
  page=yes,
  before={\blank[none]},
  after={\blank[none]},
]

\setuphead[section][
  number=no,
  before={\blank[small]},
  after={\blank[small]},
]

\definepapersize[BookPageSize][
  width=601mm,
  height=305mm,
]

\definelayout[BookPageLayout][
  backspace=10mm,
  cutspace=10mm,
  width=585mm,
  height=147mm,
  topspace=10mm,
  header=0mm,
  footer=0mm,
]

\setuppapersize[BookPageSize]
\setuplayout[BookPageLayout]

% No page number at the top.
\setupheadertexts[]
\setupfootertexts[]

\setupindenting[yes, small]

\definecolumnset[BookColumns][n=4,distance=0.0333\makeupwidth]

% left page (even page numbers)
\setupcolumnset[BookColumns:1][width=.5\makeupwidth]
\setupcolumnset[BookColumns:2][width=.125\makeupwidth]
\setupcolumnset[BookColumns:3][width=.125\makeupwidth]
\setupcolumnset[BookColumns:4][width=.125\makeupwidth]
% right page (odd page numbers)
\setupcolumnset[BookColumns:5][width=.5\makeupwidth]
\setupcolumnset[BookColumns:6][width=.125\makeupwidth]
\setupcolumnset[BookColumns:7][width=.125\makeupwidth]
\setupcolumnset[BookColumns:8][width=.125\makeupwidth]

\definecolumnsetspan[BookIllustration][n=4]

\starttext
  \startbodymatter
    \startcolumnset[BookColumns]
      \chapter[title={Title},reference={title}]
      \subsection[title={Subsubtitle},reference={subsubtitle}]
      \column

      \input ward

      \section[title={Subtitle},reference={subtitle}]

      \input knuth
      \input tufte

      \section[title={Subtitle},reference={subtitle}]

      \startformula  \frac{\dot{R}^2}{R^2} = \frac{8\pi G}{3}\rho - \frac{kc^2}{R^2}  \stopformula

      \startformula  \frac{\ddot{R}}{R} = -\frac{4\pi G}{3} \left(\rho + \frac{3p}{c^2}\right)  \stopformula

      \input tufte

      \placefigure[bots]{}{\externalfigure[https://i.imgur.com/nSBuPAA.jpg][width=\paperwidth]}
    \stopcolumnset
  \stopbodymatter
\stoptext

This code produces the following, which is pretty close:

output

Problems

There are a few issues:

  • The fourth column contains a lot of whitespace at the top.
  • The second column contains garbled text (could be a page height issue).
  • The image is displayed on the second page.

Questions

How can I resolve these issues without changing the body matter, but affording some tweaks to \placefigure such that:

  • the last column is aligned to the top;
  • the garbled text does not appear; and
  • the image is on the same page as the text?

Version

Using ConTeXt 2019.04.04 13:31.

  • 4
    \setuplayout[grid=yes] The new columnsets require gridding. – Henri Menke Apr 6 at 5:27
7

Overview

As noted elsewhere, columnsets cannot be mixed with regular text. As such, the given approach will not work as expected. Also, mixedcolumns do not provide the ability for unequal columns. The following changes resolve the issues:

  • Use the newcolumnsets module, also known as page grids
  • Ensure that the layout is using grids
  • Remove the illustration from the text, make it a background image
  • Introduce a hidden counter for the chapter (and section) numbers
  • Define a layer for illustrations
  • Create setups to use the illustration layer
  • Change the paper and column dimensions to inches
  • Remove spacing before and after formulae
  • Ensure each chapter begins on its own page
  • Define a book text layout having a height relative to the page height
  • Wrap each chapter in its own columnset

Let's take these one at a time.

Import module

Easy:

\usemodule[newcolumnsets]

Use page grids

Also easy:

\setuplayout[grid=yes]

Remove illustrations

The text is written in Markdown and the illustrations were referenced relatively to a high-resolution file. Thus all the Markdown images were removed:

!̶[̶]̶(̶.̶.̶/̶0̶1̶/̶i̶l̶l̶u̶s̶t̶r̶a̶t̶i̶o̶n̶)̶

This also eliminates duplication at the expense of an issue with leading zeros that must be addressed. (Or directories containing the illustrations could be renamed, but then they don't sort properly in the file system, numerically speaking, and who wants that? Nobody.)

Create hidden counters

To reference each background image separately, the chapter number counter must be enabled. In particular:

\setuphead[chapter][
  number=yes,
]

The code is insufficient because now the chapter number appears. Remove it and its surrounding interline space as follows:

\def\BookSectionNumber#1{}
\def\BookChapterTitle#1{#1}
\def\BookTimeline#1{#1 Ma}

\setuphead[chapter][
  number=yes,
  deeptextcommand=\BookChapterTitle,
  deepnumbercommand=\BookSectionNumber,
  before={\blank[none]},
  after={\blank[none]},
]

This introduces yet another issue: a single space between the chapter number and chapter title text. Using \hskip on the chapter with a negative value would kind of fix the problem; however, it feels more robust to simply ensure that the subsection header also has the same space. Accomplished as:

\setuphead[subsection][
  number=yes,
  deepnumbercommand=\BookSectionNumber,
  deeptextcommand=\BookTimeline,
  before={\blank[none]},
  after={\column\noindentation},
  grid=high,
]

The usage of after=... and grid=... is key. The former ensures a column break after the subsection, which represents the event time on the timeline; the latter moves the event time directly beneath the chapter title, without a large gap.

Define illustration layer

Since the illustration fits the entire page width, ensure the layer maps to the entire page as follows:

\definelayer[BookIllustrationLayer][
  width=\paperwidth,
  height=\paperheight,
  position=no,
  repeat=no,
]

Create illustration setups

Before the illustration layer can be used as a page background, it needs to dynamically update the illustration to use based on the chapter number. First, fix the zero padding (note the % symbols to avoid unsavoury whitespaces):

\def\BookIllustrationNumber{%
  \ifnum\namedheadnumber{chapter}<10 0\fi\namedheadnumber{chapter}%
}

Note: The \namedheadnumber{chapter} macro will not provide a number without first setting number=yes during \setuphead[chapter]. Next, create the setups so that ConTeXt re-evaluates the layer macros per page:

\startsetups[BookIllustrationSetups]
  \setlayerframed[BookIllustrationLayer][
    frame=off,
    x=-.025in,
    y=.5\paperheight
  ]{%
    \externalfigure[../\BookIllustrationNumber/illustration][
      width=\paperwidth,
      height=.5\paperheight
    ]%
  }%
\stopsetups

This allows the illustrations to be removed from the Markdown source file.

Note that the x=-.025in is necessary to shift the illustration to the left, thereby eliminating a sliver of whitespace along the left-hand edge.

Set paper dimensions

One of the biggest issues was that the paper width and column sets were incongruent. Knowing that the physical book is 12" by 12" (and a page spans both sides), set the paper size accordingly:

\definepapersize[BookPaperSize][
  width=24in,
  height=12in,
]

\setuppapersize[BookPaperSize]

Set column dimensions

The intended page layout resembles:

|         12"         ||  4"  |  4"  |  4"  |

However, when accounting for spacing between columns and spacing for margins, the actual numbers will differ slightly. The column sets are defined as:

\definecolumnset[BookColumns][n=4,distance=.2in]
\setupcolumnset[BookColumns:1][width=11in]
\setupcolumnset[BookColumns:2][width=3.46in]
\setupcolumnset[BookColumns:3][width=3.46in]
\setupcolumnset[BookColumns:4][width=3.46in]

Eliminate formulae space

Since grid=yes has been set, eliminate the space before and after formulae as follows:

\setupformulae[
  spacebefore=0in,
  spaceafter=0in,
]

Force chapter pagination

Force a page break before each chapter to ensure each column set begins on a new page:

\setuphead[chapter][
  number=yes,
  deeptextcommand=\BookChapterTitle,
  deepnumbercommand=\BookSectionNumber,
  page=yes,
  before={\blank[none]},
  after={\blank[none]},
]

Setting page=yes causes an unfortunate side-effect: the book is interwoven with blank pages in between chapters. These can be eliminated using Ghostscript to post-process, such as:

gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dQUIET -dBATCH \
   -sPageList=even -sOutputFile=${FILE_OUTPUT_DOC} ${FILENAME}.pdf

Passing -sPageList=even removes all the odd-numbered pages from the PDF. Having a way to suppress the extraneous blank page within ConTeXt would be ideal.

Define book text layout

To ensure that the columns don't run the entire paper height, they must be confined to a layer that is roughly half the overall height. At this point, it's possible to set some border spacing around the page as well. This resembles the following:

\definemeasure[BookTextLayoutHeight][\dimexpr .5\paperheight - 1in\relax]

\definelayout[BookTextLayout][
  topspace=.5in,
  backspace=1in,
  width=\paperwidth,
  height=\measure{BookTextLayoutHeight},
  header=\zeropoint,
  footer=\zeropoint,
]

Wrap chapters in columnsets

The Markdown documents themselves are converted to ConTeXt using pandoc. For example, the text might resemble:

# Inflation Theory
### 13,799 ± 0.021

Lorem ipsum dolor sit amet...

## Relevance

Lorem ipsum dolor sit amet...

## Knowledge

Lorem ipsum dolor sit amet...

$$ \frac{\dot{R}^2}{R^2} = \frac{8\pi G}{3}\rho - \frac{kc^2}{R^2} $$

$$ \frac{\ddot{R}}{R} = -\frac{4\pi G}{3} \left(\rho + \frac{3p}{c^2}\right) $$

This generates:

\chapter[title={Inflation Theory},reference={inflation-theory}]

\subsection[title={13,799 ± 0.021},reference={section}]

Lorem ipsum dolor sit amet...

\section[title={Relevance},reference={relevance}]

Lorem ipsum dolor sit amet...

\section[title={Knowledge},reference={knowledge}]

Lorem ipsum dolor sit amet...

\startformula  \frac{\dot{R}^2}{R^2} = \frac{8\pi G}{3}\rho - \frac{kc^2}{R^2}  \stopformula

\startformula  \frac{\ddot{R}}{R} = -\frac{4\pi G}{3} \left(\rho + \frac{3p}{c^2}\right)  \stopformula

Ideally, the entire document would be bracketed in a single column set, such as:

\starttext
  \startcolumnset[BookColumns]
    \input body
  \stopcolumnset
\stoptext

This, however, wouldn't work. In theory, it could be possible to change the chapter heading setup to use beforesection and aftersection to insert the column sets. This might resemble:

\setuphead[chapter][
  number=yes,
  deeptextcommand=\BookChapterTitle,
  deepnumbercommand=\BookSectionNumber,
  page=yes,
  beforesection={\startcolumnset[BookColumns]},
  before={\blank[none]},
  after={\blank[none]},
  aftersection={\stopcolumnset},
]

Various combinations of the before* and after* parameters would not work. So to keep the Markdown as strictly text while resolving the issue, the book's build script was changed to inject the column set macros:

sed -i 's/^\\chapter\(.*\)/\\stopcolumnset\n\\startcolumnset[BookColumns]\n\\chapter\1/' body.tex
sed -i '1d' body.tex
echo "\\stopcolumnset" >> body.tex

The script then produces the expected output:

\stopcolumnset
\startcolumnset[BookColumns]
\chapter[title={First Stars},reference={first-stars}]

I'm fairly certain this step can be eliminated in ConTeXt, but don't know how. The solution is a bit brittle due to the regex and would be superb to eliminate. It would be possible to use a pandoc filter in Lua, as well, but that doesn't really address the brittleness and separation of concerns.

Result

The final result resembles:

Single Page

Bonus Result

A preview of the layflat book, rendered using Blender:

3D Render

  • Great documentation of your progress. Really helpful! – DG' Apr 9 at 5:42
  • Any reason you stick to markdown input? I feel that for complex layout such as this example, one has to jump through a lot of hoops when using markdown source because markdown has no concept of environments or divs or ... Why not just start with context markup? – Aditya Apr 10 at 16:15
  • Pandoc introduced div concepts a while back. There's an ecosystem of tools for editing and parsing Markdown, sharing plain text documents with less technically savvy editors is expedient, avoids lock-in, and most importantly Markdown documents help ensure that the content remains independent from its presentation. (One could also ask, "Why not start with a Microsoft Word document?") – Dave Jarvis Apr 10 at 21:04

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.