如何在跨多个页面的 Page-Frame 内创建 Multicol

如何在跨多个页面的 Page-Frame 内创建 Multicol

添加于 2020-07-05 -- 我的要求详情:

制作一个包含 doublecol 和 onecol 框架的文档:

框架应该

  1. 完全框架所有内容文件的
  2. 之内一帧
  3. 那是在分页符之间(且仅在分页符之间)打开

至于内容在框架内

  1. 内容交替双列
  2. 奥内科尔

页码:我可以接受没有框架的页码,但那样就更好了。

因此理想的代码应该是这样的:


\usepackage{mdframed}                   % Alternative1
%\usepackage{framed}                    % Alternative2
\usepackage{multicol}
\usepackage{lipsum}

\begin{document}
    \begin{mdframed}                % Alternative1
    %\begin{framed}                 % Alternative2
    
        \begin{multicols}{2}
        \lipsum[1-10]       
        \end{multicols}

        \lipsum[1-2]
        
        \begin{multicols}{2}
        \lipsum[1-10]       
        \end{multicols}

    \end{mdframed}                  % Alternative1
    %\end{framed}                   % Alternatice2

\end{document}

不起作用:mdframed、framed

但是:当文本跨越多于一页例如使用\lipsum[1-10],编译器会在堆栈溢出语句中迷失

"!TeX 容量超出,抱歉 [输入堆栈大小=5000]。@xiipt ->12 \end{framed}。"

我从文档第 6 页3.1 1.4 版前言

对这种内部多列环境 (嵌套的,或在 TEX 的内部垂直模式内) 的唯一限制是,这种变体将产生一个包含平衡材料的框,因此它们不能跨页或跨列分解。

因此看起来 LaTex 正在尝试 a) 打开一个框架 b) 渲染两列 c) 无法传送页面,因为两列尚未分布在文档中,然后 d) 死亡,因为它不知道如何关闭第一页的框架。

不起作用:twocolumn 作为文档类参数

\documentclass[twocolumn]{article}
...

但这会在每一列周围产生一个框架 - 这是我所不想要的。

**不管用:

这应该没那么难——这似乎是一个很简单的常见问题。如何实现呢?

谢谢你的努力。

交叉链接 ---------------------- 德国纺织世界网 golatex.de


答案1

更新 #2 将框架大小调整到最终文本的一种方法是保存文档末尾的 y 位置,然后使用该位置计算最终页面上的“\layerheight”。

此解决方案用于zref查找该位置。您需要运行两次。

\documentclass{article}
\usepackage{scrlayer}
\usepackage{multicol}
\usepackage[savepos]{zref}
\usepackage{lipsum}

\newlength{\marginpadding}
\setlength{\marginpadding}{4pt}

\DeclareNewLayer[textarea,background,mode=picture,
  addheight=2\marginpadding,
  addwidth=2\marginpadding,
  addhoffset=-\marginpadding,
  addvoffset=-\marginpadding,
  contents={%
  \putLR{\line(0,1){\LenToUnit{\layerheight}}}%
  \putUR{\line(-1,0){\LenToUnit{\layerwidth}}}%
  \putUL{\line(0,-1){\LenToUnit{\layerheight}}}%
}]{topbox}
\DeclareNewLayer[clone=topbox,
  contents={%
  \putLR{\line(0,1){\LenToUnit{\layerheight}}}%
  \putUL{\line(0,-1){\LenToUnit{\layerheight}}}%
}]{midbox}
\DeclareNewLayer[clone=topbox,
  height={\pdfpageheight-\zposy{textbottom}sp-\layeryoffset-\baselineskip+\marginpadding},
  contents={%
  \putLL{\line(1,0){\LenToUnit{\layerwidth}}}%
  \putLR{\line(0,1){\LenToUnit{\layerheight}}}%
  \putUL{\line(0,-1){\LenToUnit{\layerheight}}}%
}]{bottombox}
\DeclarePageStyleByLayers{firstpage}{topbox}
\DeclarePageStyleByLayers{midpage}{midbox}
\DeclarePageStyleByLayers{lastpage}{bottombox}
\pagestyle{midpage}
\begin{document}
\thispagestyle{firstpage}
\begin{multicols}{2}
  \lipsum[1-10]       
\end{multicols}

\lipsum[1-2]

\begin{multicols}{2}
  \lipsum[1-10]
\end{multicols}
\zsaveposy{textbottom}
\thispagestyle{lastpage}
\end{document}

最终页面的框架

更新答案(2020/07/06)

我仍然不完全清楚您的要求,但如果您真正要求的是一个大小固定且仅根据您所在的页面调整其形状的框架,那么您可以使用包提供的页面样式来实现scrlayer

只要您知道内容不止一页,下面的方法就有效。(如果确实需要,您可以添加一些逻辑来测试单页文档。)基本思路是创建三种页面样式,将中间页面样式设为默认样式,并在开始和结束处设置单个页面的顶部和底部样式。

框架非常简单(它改编自 KOMA-Script 手册——参见第 17 章),但如果您愿意,您可以用更复杂的图像替换内容。

\documentclass{article}
\usepackage{scrlayer}
\usepackage{multicol}
\usepackage{lipsum}

\newlength{\marginpadding}
\setlength{\marginpadding}{4pt}

\DeclareNewLayer[textarea,background,mode=picture,
  addheight=2\marginpadding,addwidth=2\marginpadding,
  addhoffset=-\marginpadding,addvoffset=-\marginpadding,
  contents={%
  \putLR{\line(0,1){\LenToUnit{\layerheight}}}%
  \putUR{\line(-1,0){\LenToUnit{\layerwidth}}}%
  \putUL{\line(0,-1){\LenToUnit{\layerheight}}}%
}]{topbox}
\DeclareNewLayer[textarea,background,mode=picture,
  addheight=2\marginpadding,addwidth=2\marginpadding,
  addhoffset=-\marginpadding,addvoffset=-\marginpadding,
  contents={%
  \putLR{\line(0,1){\LenToUnit{\layerheight}}}%
  \putUL{\line(0,-1){\LenToUnit{\layerheight}}}%
}]{midbox}
\DeclareNewLayer[textarea,background,mode=picture,
  addheight=2\marginpadding,
  addwidth=2\marginpadding,
  addhoffset=-\marginpadding,
  addvoffset=-\marginpadding,
  contents={%
  \putLL{\line(1,0){\LenToUnit{\layerwidth}}}%
  \putLR{\line(0,1){\LenToUnit{\layerheight}}}%
  \putUL{\line(0,-1){\LenToUnit{\layerheight}}}%
}]{bottombox}
\DeclarePageStyleByLayers{firstpage}{topbox}
\DeclarePageStyleByLayers{midpage}{midbox}
\DeclarePageStyleByLayers{lastpage}{bottombox}
\pagestyle{midpage}
\begin{document}
\thispagestyle{firstpage}
\begin{multicols}{2}
  \lipsum[1-10]       
\end{multicols}

\lipsum[1-2]

\begin{multicols}{2}
  \lipsum[1-10]       
\end{multicols}
\thispagestyle{lastpage}
\end{document}

原始答案

欢迎来到 Tex.SE。

您可以尝试该包multicolrule。这个想法是为多列创建一个“列分隔符”,实际上在列的外部而不是列之间绘制一个框。

\documentclass{article}
\usepackage[tikz]{multicolrule}
\usetikzlibrary{calc}
\usepackage{lipsum}

\SetMCRule{color=gray,width=0.4pt, expand=2pt, custom-line={
  \coordinate (TOPLEFT) at ($(TOP)-(\columnwidth+.5\columnsep,\columnseprule)$);
  \coordinate (TOPRIGHT) at ($(TOP)+(\columnwidth+.5\columnsep,-\columnseprule)$);
  \coordinate (BOTLEFT) at ($(BOT)-(\columnwidth+.5\columnsep,-\columnseprule)$);
  \coordinate (BOTRIGHT) at ($(BOT)+(\columnwidth+.5\columnsep,\columnseprule)$);
  \draw[line width=\columnseprule] (TOPLEFT) -- (TOPRIGHT) -- (BOTRIGHT) -- (BOTLEFT) -- cycle;}}

\begin{document}
\begin{multicols}{2}
  \lipsum
\end{multicols}
\end{document}

此版本将线条精确地放置在框的边缘周围,但是您可以根据需要添加间隙。

相关内容