TikZ 框架段落跨越 ConTeXt 中的页面

TikZ 框架段落跨越 ConTeXt 中的页面

我尝试在 ConTeXt 中重现以下示例:
http://www.texample.net/tikz/examples/framed-tikz/

我怎样才能替代 LaTeXframed包,使框架跨越多个页面?
(放弃 TikZ 不是一个选择,因为我已经设计了自己的框架。)

答案1

你可以使用机制来实现这一点。你可以使用和background来获取框的宽度和高度。以下是示例:\overlaywidth\overlayheight

\usemodule[tikz]

\startsetups tikz:frame
  \starttikzpicture 
    \filldraw[fill=lightgray] (0,0) -- (0, \overlayheight) -- (\overlaywidth, \overlayheight) -- (\overlaywidth,0) -- cycle;
  \stoptikzpicture
\stopsetups 

\defineoverlay[tikzframe][\setups{tikz:frame}]

\definebackground[tikzframe][background=tikzframe]

\starttext

\starttikzframe
  \dorecurse{10}{\input knuth \endgraf}
\stoptikzframe

\stoptext

这使

在此处输入图片描述

编辑:@user19041 在评论中询问是否可以根据状态分割。ConTeXt 确实有一个内部宏\backgroundsplitmode,用于跟踪\vbox分割的方式。不幸的是,它没有区分 vbox 不需要分割的情况和 vbox 已分割但我们在最后一页的情况。区分这两种情况很容易(前提是您没有嵌套这样的框架;在这种情况下,我们需要为每个嵌套级别定义一个新的计数器)。下面的示例说明了如何做到这一点。我刚刚更改了背景颜色来说明这个概念。

\usemodule[tikz]

\setnewconstant\tikzbackgroundstate\zerocount

\definecolor[backgroundcolor][lightgray]

\startsetups tikz:frame
  \starttikzpicture 
    \ifcase \backgroundsplitmode
      % Case 0: no split or last page
      \ifcase\tikzbackgroundstate
        % The frame does not split across pages
        \definecolor[backgroundcolor][lightgray]
      \else
        % Last page of a split frame
        \definecolor[backgroundcolor][red]
      \fi \or 
      % Case 1: split to max height, always middle page
        \definecolor[backgroundcolor][yellow]
        \global\tikzbackgroundstate=\plusone
      \else
      % Case 2: split to partial height. Always first page
        \definecolor[backgroundcolor][green]
        \global\tikzbackgroundstate=\plustwo
      \fi
        \filldraw[fill=backgroundcolor] (0,0) -- (0, \overlayheight) -- (\overlaywidth, \overlayheight) -- (\overlaywidth,0) -- cycle;
  \stoptikzpicture
\stopsetups 

\defineoverlay[tikzframe][\setups{tikz:frame}]

\definebackground[tikzinternalframe][background=tikzframe]

\define\starttikzframe
    {\dosingleargument\dostarttikzframe}

\def\dostarttikzframe[#1]%
    {\tikzbackgroundstate=\zerocount
     \starttikzinternalframe[#1]}

\define\stoptikzframe{\stoptikzinternalframe}



\starttext

\starttikzframe
\input ward
\stoptikzframe

\blank[big]

\starttikzframe
  \dorecurse{11}{\input knuth \endgraf}
\stoptikzframe



\stoptext

这使

在此处输入图片描述

答案2

我当前的解决方案草案基于以下问题的答案可破坏的垂直盒子

\usemodule[tikz]
\pgfdeclarelayer {background}
\pgfsetlayers {background,main}

\newbox\totalbox
\newbox\partialbox
\newdimen\partialboxdim

\def\startframedbox{\par\bigskip
\setbox\totalbox=\vbox\bgroup\advance\hsize by -8pt}
\def\endframedbox{\egroup\splitframedbox}

\def\splitframedbox{\ifvoid\totalbox\finishframedbox
  \else\continuesplitting\fi}
\def\finishframedbox{\bigskip}

\newdimen\Distance

\def\continuesplitting{\null%
  \Distance=\dimexpr\pagegoal-\pagetotal-\pageshrink-6pt\relax
  \ifdim\ht\totalbox<\Distance
    \setbox\partialbox=\box\totalbox
    \framethisbox
  \else
    \setbox\partialbox=\vsplit\totalbox to\dimexpr\Distance-5pt\relax
    \framethisbox
    \vfill\page
  \fi
  \splitframedbox}

\def\framethisbox{%
\starttikzpicture
    \node (A) {\hbox{\vbox{\unvbox\partialbox}}};
    \startpgfonlayer{background}
        \filldraw[draw=black,fill=lightgray] (A.north east) -- (A.north west) -- (A.south west) -- (A.south east) -- cycle;
    \stoppgfonlayer{background}
\stoptikzpicture%
}

\starttext

\input knuth

\startframedbox
  \dorecurse{15}{\input knuth\par}
\endframedbox

\input knuth

\stoptext

此代码在文本周围绘制一个细框并添加灰色背景,但任何有效的 TikZ 代码都可以使用。

相关内容