在 ConTeXt 的列集/页面列中添加列规则

在 ConTeXt 的列集/页面列中添加列规则

这是我第一次使用 ConText,虽然我认为我有一些不错的编程经验,但 TeX 代码是我以前从未接触过的东西(并且让我感到很害怕)。

长话短说,我试图获得一个三列布局,其中每列有垂直规则分隔,就像《科学》杂志一样:

在此处输入图片描述

我对列集和页面列进行了一些尝试(按照 wiki 上的建议),但我很难得到我想要的规则。Wiki 建议使用一些 METAFUN 代码来绘制规则,但不幸的是,这并不是我想要的:

  1. 页面右侧有一条不必要的规则——对于N列数,我总是希望用N - 1规则将它们分开
  2. 这些规则一直延续到文本结束后,甚至在列中根本没有文本时也会进行绘制!

我现在的位置是:

% Margins
\setuplayout[
  backspace=13mm, width=middle,
  topspace=13mm, height=middle,
  header=0mm, footer=0mm]

% Page Columns
\startuseMPgraphic{verticalrule}
  if CurrentColumn < 3 :
    draw rightboundary OverlayBox shifted (4mm,0);
    setbounds currentpicture to OverlayBox enlarged 2.5mm;
  fi
\stopuseMPgraphic

\defineoverlay
  [verticalrule]
  [\useMPgraphic{verticalrule}]

\startpagecolumns[n=3,background=verticalrule]

给我: 在此处输入图片描述 第二页展示了第二期: 在此处输入图片描述

说实话,我在获取实际文本的高度时遇到了困难(不是整个文本区域,而是非空白区域),而且在玩 METAFUN 时,我找不到绕过额外规则的方法。也许我需要将这一切都作为页面背景而不是列覆盖?但这对我的问题 #2 有什么帮助?

我将非常感激您提供的任何帮助!

提前致谢!

布鲁克斯

编辑:

以下是一些最小工作示例的代码!删除自定义字体后,文本变大了一点,底部边缘有些参差不齐(这是怎么回事?):

% Common Imports
\usemodule[ipsum]

% Basic Document Setup
\mainlanguage[en]
\setuppapersize[A4]

% Margins
\setuplayout[
  backspace=13mm, width=middle,
  topspace=13mm, height=middle,
  header=0mm, footer=0mm]

% Page Columns
\startuseMPgraphic{verticalrule}
  if CurrentColumn < 3 :
    draw rightboundary OverlayBox shifted (4mm,0);
    setbounds currentpicture to OverlayBox enlarged 2.5mm;
  fi
\stopuseMPgraphic

\defineoverlay
  [verticalrule]
  [\useMPgraphic{verticalrule}]

\startpagecolumns[n=3,background=verticalrule]

% Dummy Text
\starttext
\setupalign[tolerant,stretch,hanging,hz]
\ipsum
\ipsum

\ipsum
\ipsum

\ipsum

\ipsum
\ipsum

\ipsum
\stoptext

双重编辑: 这是我的输出context -version

mtx-context     | ConTeXt Process Management 1.04
mtx-context     |
mtx-context     | main context file: /usr/share/texmf-dist/tex/context/base/mkiv/context.mkiv
mtx-context     | current version: 2021.03.05 19:11
mtx-context     | main context file: /usr/share/texmf-dist/tex/context/base/mkxl/context.mkxl
mtx-context     | current version: 2021.03.05 19:11

当我运行 Wolfgang 建议的代码时context Article.tex

resolvers       | formats | executing runner 'run luatex format': /usr/bin/luatex --jobname="Article" --fmt=/home/tll/.texlive/texmf-var/luatex-cache/context/0399a8df3aef8d154781d0a9c2b8e28d/formats/luatex/cont-en.fmt --lua=/home/tll/.texlive/texmf-var/luatex-cache/context/0399a8df3aef8d154781d0a9c2b8e28d/formats/luatex/cont-en.lui cont-yes.mkiv --c:currentrun=1 --c:fulljobname="./Article.tex" --c:input="./Article.tex" --c:kindofrun=1 --c:maxnofruns=9 --c:texmfbinpath="/usr/bin"
This is LuaTeX, Version 1.15.0 (TeX Live 2022/Arch Linux) 
 system commands enabled.
open source     > level 1, order 1, name '/usr/share/texmf-dist/tex/context/base/mkiv/cont-yes.mkiv'
system          > 
system          > ConTeXt  ver: 2021.03.05 19:11 MKIV  fmt: 2022.5.17  int: english/english
system          > 
system          > 'cont-new.mkiv' loaded
open source     > level 2, order 2, name '/usr/share/texmf-dist/tex/context/base/mkiv/cont-new.mkiv'
system          > beware: some patches loaded from cont-new.mkiv
close source    > level 2, order 2, name '/usr/share/texmf-dist/tex/context/base/mkiv/cont-new.mkiv'
system          > files > jobname 'Article', input './Article', result 'Article'
fonts           > latin modern fonts are not preloaded
languages       > language 'en' is active
open source     > level 2, order 3, name '/home/spinning/tll/Documents/University/Y4S2/Literature Review/ConTeXt (RIP)/Article.tex'
fonts           > preloading latin modern fonts (second stage)
fonts           > 'fallback modern-designsize rm 12pt' is loaded

Underfull \hbox (badness 1342) in paragraph at lines 1--36
<1: lmroman12-regular @ 12.0pt> sem-per quis fringilla ut, viverra

Underfull \hbox (badness 1342) in paragraph at lines 1--36
<1: lmroman12-regular @ 12.0pt> sem-per quis fringilla ut, viverra

Underfull \hbox (badness 1342) in paragraph at lines 1--36
<1: lmroman12-regular @ 12.0pt> sem-per quis fringilla ut, viverra

Underfull \hbox (badness 1342) in paragraph at lines 1--36
<1: lmroman12-regular @ 12.0pt> sem-per quis fringilla ut, viverra

Underfull \hbox (badness 1342) in paragraph at lines 1--36
<1: lmroman12-regular @ 12.0pt> sem-per quis fringilla ut, viverra

Underfull \hbox (badness 1342) in paragraph at lines 1--36
<1: lmroman12-regular @ 12.0pt> sem-per quis fringilla ut, viverra

Underfull \hbox (badness 1342) in paragraph at lines 1--36
<1: lmroman12-regular @ 12.0pt> sem-per quis fringilla ut, viverra

Underfull \hbox (badness 1342) in paragraph at lines 1--36
<1: lmroman12-regular @ 12.0pt> sem-per quis fringilla ut, viverra

Underfull \hbox (badness 1342) in paragraph at lines 1--36
<1: lmroman12-regular @ 12.0pt> sem-per quis fringilla ut, viverra
metapost        > initializing instance 'metafun:1' using format 'metafun' and method 'default'
metapost        > loading 'metafun' as '/usr/share/texmf-dist/metapost/context/base/mpiv/metafun.mpiv' using method 'default'
metapost        > initializing number mode 'scaled'
backend         > xmp > using file '/usr/share/texmf-dist/tex/context/base/mkiv/lpdf-pdx.xml'
pages           > flushing realpage 1, userpage 1, subpage 1
pages           > flushing realpage 2, userpage 2, subpage 2
close source    > level 2, order 3, name '/home/spinning/tll/Documents/University/Y4S2/Literature Review/ConTeXt (RIP)/Article.tex'
close source    > level 1, order 3, name '/usr/share/texmf-dist/tex/context/base/mkiv/cont-yes.mkiv'

mkiv lua stats  > used config file: selfautodir:/share/texmf-dist/web2c/texmfcnf.lua
mkiv lua stats  > used cache path: readable+writable: '/home/tll/.texlive/texmf-var/luatex-cache/context/0399a8df3aef8d154781d0a9c2b8e28d'
mkiv lua stats  > resource resolver: loadtime 0.055 seconds, 0 scans with scantime 0.000 seconds, 0 shared scans, 31 found files, scanned paths: <none>
mkiv lua stats  > stored bytecode data: 454 modules (0.176 sec), 96 tables (0.008 sec), 550 chunks (0.183 sec)
mkiv lua stats  > traced context: maxstack: 1422, freed: 2, unreachable: 1420
mkiv lua stats  > cleaned up reserved nodes: 57 nodes, 9 lists of 442
mkiv lua stats  > node memory usage: 17 attribute, 6 attribute_list, 3 glue, 51 glue_spec, 3 kern, 4 penalty, 2 temp, 2 user_defined
mkiv lua stats  > node list callback tasks: 8 unique task lists, 7 instances (re)created, 374 calls
mkiv lua stats  > driver time: 0.050 seconds 
mkiv lua stats  > used backend: pdf (backend for directly generating pdf output)
mkiv lua stats  > jobdata time: 0.001 seconds saving, 0.000 seconds loading
mkiv lua stats  > callbacks: internal: 842, file: 229, direct: 2, late: 18, function 627, total: 1718 (859 per page)
mkiv lua stats  > randomizer: resumed with value 0.47691170172766
mkiv lua stats  > positions: 3 collected, 3 regular, 0 special
mkiv lua stats  > result saved in file: Article.pdf, compresslevel 3, objectcompresslevel 1
mkiv lua stats  > loaded patterns: en::1, load time: 0.000
mkiv lua stats  > loaded fonts: 2 files: latinmodern-math.otf, lmroman12-regular.otf
mkiv lua stats  > font engine: otf 3.113, afm 1.513, tfm 1.000, 7 instances, 3 shared in backend, 3 common vectors, 0 common hashes, load time 0.106 seconds 
mkiv lua stats  > metapost: 0.001 seconds, loading: 0.010, execution: 0.001, n: 8, average: 0.001, instances: 1, luacalls: 56, memory: 2.851 M
mkiv lua stats  > used platform: linux-64, type: unix, binary subtree: usr
mkiv lua stats  > used engine: luatex version: 1.15, functionality level: 7509, banner: this is luatex, version 1.15.0 (tex live 2022/arch linux)
mkiv lua stats  > used hash slots: 46520 of 65536 + 200000
mkiv lua stats  > lua properties: engine: lua 5.3, used memory: 147 MB, ctx: 147 MB, max: unknown MB, hash chars: min(64,40), symbol mask: utf (τεχ)
mkiv lua stats  > runtime: 0.396 seconds, 2 processed pages, 2 shipped pages, 5.051 pages/second
system          | total runtime: 0.572 seconds

在最后一栏之后,仍然会出现同样的规则问题: 在此处输入图片描述

答案1

在与 Hans 讨论后(并得到了 Wolfgang 的有益建议),以下解决方案问世了。如果列不平衡,此方法效果很好。我没有做主要工作,因此我不想承担责任,并将其标记为 CW。

\setupbodyfont[dejavu,9pt]

\setuphead[subject][
    style=bold,
    before={\blank[line]},
    after={\blank[none]},
]


\setuplayout[
    backspace=13mm,
    width=middle,
    topspace=13mm,
    height=middle,
    header=0mm,
    footer=0mm,
    grid=yes,
]


\startuseMPgraphic{verticalrule}
save a, b, c, p, q, r ;
path b ; b := positioncolumnbox(CurrentColumn) ;
draw image (
    path p ; p := rightboundary b shifted (\frameddimension{distance}/2,0) ;
    numeric c ; c := positioncolumn(positionregion("allendshere")) ;
    if (positionpage("allendshere") = RealPageNumber):
        if (CurrentColumn < c) :
            draw p withcolor black withpen pencircle scaled 1 ;
        elseif (CurrentColumn > c) :
            % nothing
        else :
            if CurrentColumn < NOfColumns :
                pair a ; a := positionxy ("allendshere") ;
                path q ; q := (0,ypart a) -- (PaperWidth,ypart a) ;
                path r ; r := p cutbeforefirst q ;
                draw r withcolor black withpen pencircle scaled 1 ;
            fi ;
        fi ;
    else :
        if CurrentColumn < NOfColumns :
            draw p withcolor black withpen pencircle scaled 1 ;
        fi ;
    fi ;
) shifted -llcorner b ;
setbounds currentpicture to OverlayBox ;
\stopuseMPgraphic

\defineoverlay[verticalrule][\useMPgraphic{verticalrule}]

\setupalign[verytolerant,stretch]

\starttext

\startpagecolumns[n=3,background=verticalrule]
    \dorecurse{10}{%
        \subject[title={Foo \recurselevel}]
        \samplefile{lorem}
    }
    \hpos{allendshere}{}
\stoppagecolumns

\stoptext

具有规则的列

答案2

支持pagecolumns分隔列的规则,但是规则本身的代码已被注释,无法使用。

如果代码已启用,您可以启用分隔符,separator=rule但目前这不是一个选项。

\setuplayout [tight]

\starttext

\startpagecolumns [n=3,align={verytolerant,stretch},separator=rule]
\dorecurse{10}{\samplefile{lorem}}
\stoppagecolumns

\stoptext

您可以做的是为每一列创建自己的背景并使用两个寄存器\nofcolumns\mofcolumns检查当前列是否也是最后一列。

这两个寄存器在 MetaFun 中都有自己的名称,可以在 if 条件中使用。

% \startuseMPgraphic {ColumnSeparator}
%     \ifnum\mofcolumns<\nofcolumns
%         draw rightboundary (OverlayBox rightenlarged \measure{ColumnOffset});
%         setbounds currentpicture to OverlayBox;
%     \fi
% \stopuseMPgraphic

\startuseMPgraphic {ColumnSeparator}
    if CurrentColumn < NOfColumns:
        draw rightboundary (OverlayBox rightenlarged \measure{ColumnOffset});
        setbounds currentpicture to OverlayBox;
    fi
\stopuseMPgraphic

\defineoverlay [ColumnSeparator] [\useMPgraphic{ColumnSeparator}]

\setuplayout [tight]

\definemeasure [ColumnDistance] [1em]
\definemeasure [ColumnOffset]   [\measure{ColumnDistance}/2]

\starttext

\startpagecolumns [n=3,align={verytolerant,stretch},background=ColumnSeparator,distance=\measure{ColumnDistance}]
\dorecurse{10}{\samplefile{lorem}}
\stoppagecolumns

\stoptext

在此处输入图片描述

在此处输入图片描述

答案3

延伸沃尔夫冈的回答使用 Lua 回调来测量列高。

(编辑以修复一个小错误)

\doifnot{\contextmark}{LMTX}{
    \errmessage{"LMTX/MkXL is required to compile this file."}
}

\startluacode
    local saved_data = job.passes.define("column_height")
    local previous_data = job.passes.getcollected("column_height")
    local bigpoint = tex.sp("1bp")

    -- Run this code every time we output a column:
    callback.register("pre_output_filter", function(head)
        -- Measure the height of the column (head.next to avoid the topskip)
        local column_height = node.vpack(head.next).height
        local pagenumber = tex.count.realpageno
        -- Get the natural width of the baselineskip
        local baselineskip = tex.skip.baselineskip.width

        -- Save the column height in the .tuc file
        saved_data[pagenumber] = saved_data[pagenumber] or {}
        table.insert(
            saved_data[pagenumber],
            -- Clamp the height to multiples of baselineskip
            math.ceil(column_height / baselineskip) * baselineskip
        )

        return head
    end)

    function column_height(col)
        local pagedata = previous_data[tex.count.realpageno]
        if not pagedata then
            mp.numeric(0)
            texio.write_nl("Please rerun!")
            return
        end
        -- Get the minimum height of the column on either side of the line
        local minimum = math.max(pagedata[col], pagedata[col + 1])
        mp.numeric(-minimum / bigpoint)
    end
\stopluacode

% Draw the separator rules:
\startuseMPgraphic {ColumnSeparator}
    if CurrentColumn < NOfColumns:
        draw urcorner OverlayBox shifted (\measure{ColumnOffset}, 0pt) --
             urcorner OverlayBox shifted
                 (\measure{ColumnOffset}, lua.column_height(CurrentColumn));
        setbounds currentpicture to OverlayBox;
    fi
\stopuseMPgraphic

\defineoverlay [ColumnSeparator] [\useMPgraphic{ColumnSeparator}]

\setuplayout [tight]

\definemeasure [ColumnDistance] [1em]
\definemeasure [ColumnOffset]   [\measure{ColumnDistance}/2]

\starttext

\startpagecolumns [n=3,align={verytolerant,stretch},background=ColumnSeparator,distance=\measure{ColumnDistance}]
\dorecurse{10}{\samplefile{lorem}}
\stoppagecolumns

\stoptext

输出的第 1 页

输出的第 2 页

上面,分隔符规则是两列中最短列的长度。如果用 替换math.minmath.max规则将是两列中最长列的长度。

这也适用于不同高度的柱子:

% Insert everything before `\starttext` from the code above,
% EXCEPT with `math.min` replaced with `math.max`
\setuppapersize[legal, landscape]

\starttext

\startpagecolumns [n=5,align={verytolerant,stretch},background=ColumnSeparator,distance=\measure{ColumnDistance}]

\dorecurse{2}{\samplefile{zapf}\par}
\column
\dorecurse{1}{\samplefile{lorem}\par}
\column
\dorecurse{2}{\samplefile{bryson}\par}
\column
\dorecurse{3}{\samplefile{knuth}\par}
\stoppagecolumns

\stoptext

第二个例子

相关内容