背景
希望从 Markdown 源文档中实现相当复杂的布局。布局类似于:
代码
\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
该代码产生的结果非常接近:
问题
有几个问题:
- 第四列顶部有很多空白。
- 第二列包含乱码文本(可能是页面高度问题)。
- 图像显示在第二页。
问题
我该如何解决这些问题不改变身体状况但进行了一些调整,\placefigure
例如:
- 最后一列与顶部对齐;
- 乱码文本不会出现;并且
- 图像和文本在同一页面上吗?
版本
使用 ConTeXt 2019.04.04 13:31
。
答案1
概述
作为在其他地方提到,列集不能与常规文本混合。因此,给定的方法将无法按预期工作。此外,混合列不提供不等列的功能。以下更改可解决该问题:
- 使用新栏目集模块,也称为页面网格
- 确保布局使用网格
- 从文本中删除插图,使其成为背景图像
- 引入一个隐藏的计数器来计数章节(和部分)编号
- 定义插图图层
- 创建设置以使用插图层
- 将纸张和列尺寸更改为英寸
- 删除公式前后的空格
- 确保每个章节都从自己的页面开始
- 定义一个相对于页面高度的书籍文本布局
- 将每一章包装在其自己的列集中
让我们逐一讨论这些问题。
导入模块
简单的:
\usemodule[newcolumnsets]
使用页面网格
同样简单:
\setuplayout[grid=yes]
删除插图
文本是用 Markdown 编写的,插图是相对于高分辨率文件引用的。因此删除了所有 Markdown 图像:
!̶[̶]̶(̶.̶.̶/̶0̶1̶/̶i̶l̶l̶u̶s̶t̶r̶a̶t̶i̶o̶n̶)̶
这也消除了重复,但必须解决前导零的问题。(或者可以重命名包含插图的目录,但从数字上讲,它们在文件系统中无法正确排序,谁想要这样?没有人。)
创建隐藏计数器
要单独引用每个背景图像,必须启用章节编号计数器。特别是:
\setuphead[chapter][
number=yes,
]
代码不够完善,因为现在出现了章节号。删除它及其周围的行间空格,如下所示:
\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]},
]
这又引入了另一个问题:章节号和章节标题文本之间有一个空格。\hskip
在章节上使用负值可以解决这个问题;但是,确保小节标题也具有相同的空格感觉更可靠。完成如下:
\setuphead[subsection][
number=yes,
deepnumbercommand=\BookSectionNumber,
deeptextcommand=\BookTimeline,
before={\blank[none]},
after={\column\noindentation},
grid=high,
]
after=...
和的使用grid=...
是关键。前者确保在小节之后有一个分栏,这代表了时间线上的事件时间;后者将事件时间直接移到章节标题下方,没有太大的间隙。
定义插图图层
由于插图适合整个页面宽度,请确保图层映射到整个页面,如下所示:
\definelayer[BookIllustrationLayer][
width=\paperwidth,
height=\paperheight,
position=no,
repeat=no,
]
创建插图设置
在插图层可用作页面背景之前,它需要根据章节号动态更新要使用的插图。首先,修复零填充(注意符号%
以避免令人讨厌的空格):
\def\BookIllustrationNumber{%
\ifnum\namedheadnumber{chapter}<10 0\fi\namedheadnumber{chapter}%
}
注意:如果未在 期间\namedheadnumber{chapter}
先进行设置,则宏不会提供数字。接下来,创建设置,以便 ConTeXt 重新评估每页的层宏:number=yes
\setuphead[chapter]
\startsetups[BookIllustrationSetups]
\setlayerframed[BookIllustrationLayer][
frame=off,
x=-.025in,
y=.5\paperheight
]{%
\externalfigure[../\BookIllustrationNumber/illustration][
width=\paperwidth,
height=.5\paperheight
]%
}%
\stopsetups
这可以将插图从 Markdown 源文件中删除。
请注意,需要x=-.025in
将插图向左移动,从而消除一小片空白沿着左边。
设置纸张尺寸
最大的问题之一是纸张宽度和列集不一致。已知实体书的尺寸为 12 英寸 x 12 英寸(一页横跨两边),请相应地设置纸张大小:
\definepapersize[BookPaperSize][
width=24in,
height=12in,
]
\setuppapersize[BookPaperSize]
设置列尺寸
预期的页面布局类似于:
| 12" || 4" | 4" | 4" |
但是,当考虑列间距和边距时,实际数字会略有不同。列集定义如下:
\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]
消除公式空间
由于grid=yes
已经设置,消除前后空格公式如下:
\setupformulae[
spacebefore=0in,
spaceafter=0in,
]
强制章节分页
强制在每一章之前进行分页,以确保每一列都从新页面开始:
\setuphead[chapter][
number=yes,
deeptextcommand=\BookChapterTitle,
deepnumbercommand=\BookSectionNumber,
page=yes,
before={\blank[none]},
after={\blank[none]},
]
设置page=yes
会导致一个不良副作用:书中章节之间交织着空白页。可以使用以下方法消除这些空白页Ghostscript进行后期处理,例如:
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dQUIET -dBATCH \
-sPageList=even -sOutputFile=${FILE_OUTPUT_DOC} ${FILENAME}.pdf
传递-sPageList=even
会从 PDF 中删除所有奇数页。如果能有办法在 ConTeXt 中抑制多余的空白页,那就再好不过了。
定义书籍文本布局
为了确保列不会占据整个纸张高度,必须将它们限制在大约为总高度一半的层中。此时,也可以在页面周围设置一些边框间距。这类似于以下内容:
\definemeasure[BookTextLayoutHeight][\dimexpr .5\paperheight - 1in\relax]
\definelayout[BookTextLayout][
topspace=.5in,
backspace=1in,
width=\paperwidth,
height=\measure{BookTextLayoutHeight},
header=\zeropoint,
footer=\zeropoint,
]
将章节包装在列集中
Markdown 文档本身使用以下方式转换为 ConTeXt潘多克。例如,文本可能类似于:
# 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) $$
这将生成:
\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
理想情况下,整个文档应该放在一个列集合中,例如:
\starttext
\startcolumnset[BookColumns]
\input body
\stopcolumnset
\stoptext
然而,这行不通。理论上,可以改变章节标题设置使用beforesection
并aftersection
插入列集。这可能类似于:
\setuphead[chapter][
number=yes,
deeptextcommand=\BookChapterTitle,
deepnumbercommand=\BookSectionNumber,
page=yes,
beforesection={\startcolumnset[BookColumns]},
before={\blank[none]},
after={\blank[none]},
aftersection={\stopcolumnset},
]
before*
和参数的各种组合after*
都不起作用。因此,为了在解决问题的同时保持 Markdown 严格为文本,本书的构建脚本被更改为注入列集宏:
sed -i 's/^\\chapter\(.*\)/\\stopcolumnset\n\\startcolumnset[BookColumns]\n\\chapter\1/' body.tex
sed -i '1d' body.tex
echo "\\stopcolumnset" >> body.tex
然后脚本会产生预期的输出:
\stopcolumnset
\startcolumnset[BookColumns]
\chapter[title={First Stars},reference={first-stars}]
我相当确定 ConTeXt 中可以消除这一步,但不知道怎么做。由于正则表达式,该解决方案有点脆弱,消除它会非常好。也可以在 Lua 中使用 pandoc 过滤器,但这并不能真正解决脆弱性和关注点分离问题。
结果
最终结果类似于:
奖金结果
平放书的预览,使用搅拌机: