
我嘗試在 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
我目前的解決方案草案是基於以下問題的答案可破壞的vbox:
\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 程式碼都應該可以工作。