测试某个段落是否有分页符?

测试某个段落是否有分页符?

我正在尝试使用 TikZ 制作更精美的框架。我使用了一个聪明的\tikzmark方法安德鲁·史黛西写道将节点放在环境主体的左上角和右下角。

然后我用这些节点来绘制时髦的装饰。我确信我正在重新发明轮子,但我正在学习,所以一切都很好。我知道我想做的事情是可能的,因为mdframed两者listings都能做到这一点,但它们的代码对我来说很难阅读,也不清楚相关部分是什么……

现在,这可以正常工作,直到环境跨越一页。然后节点位于不同的页面上,当环境的结束代码来绘制装饰时,它找不到左上角的节点(因为它已在最后一页上发货)。

因此,我希望针对页面环境中断的情况设置不同的行为。当段落像这样中断时,最简单的测试方法是什么?

答案1

您可以将和模块zref一起使用(例如加载和包),并在段落开头的和段落结尾处添加一个。如果您使用环境,只需在和处放置一个。然后您可以在环境末尾检查两者的绝对页码是否相同。为此,您可以使用:absposuserzref-absposzref-user\zlabel{labelname}\tikzmarkbeginend

\ifnum\zref@extract{<begin-label>}{abspage}=\zref@extract{<end-label>}{abspage}\relax
   <same page>
\else
   <different page>
\fi

(注意:也许\zref@extractdefault更好,因为您可以提供在标签尚未设置时用于第一次运行的默认值。)

另请参阅我的回答如何在文本下方而不是上方绘制文本锚定的 tikz 线?我做了一些非常相似的事情!


我现在想出了一个解决方案。如果结束宏不在同一页,它会在开始宏中绘制第一半边框。此外,环境跨越两页以上的情况(例如从第 1 页开始并结束于第 3 页)由额外的代码覆盖。

\documentclass[twoside]{book}

\usepackage{zref-abspage}
\usepackage{zref-user}
\usepackage{tikz}
\usepackage{atbegshi}
\usetikzlibrary{calc}

\makeatletter
\newcommand{\currentsidemargin}{%
  \ifodd\zref@extract{textarea-\thetextarea}{abspage}%
    \oddsidemargin%
  \else%
    \evensidemargin%
  \fi%
}

\newcounter{textarea}
\newcommand{\settextarea}{%
   \stepcounter{textarea}%
   \zlabel{textarea-\thetextarea}%
   \begin{tikzpicture}[overlay,remember picture]
    % Helper nodes
    \path (current page.north west) ++(\hoffset, -\voffset)
        node[anchor=north west, shape=rectangle, inner sep=0, minimum width=\paperwidth, minimum height=\paperheight]
        (pagearea) {};
    \path (pagearea.north west) ++(1in+\currentsidemargin,-1in-\topmargin-\headheight-\headsep)
        node[anchor=north west, shape=rectangle, inner sep=0, minimum width=\textwidth, minimum height=\textheight]
        (textarea) {};
  \end{tikzpicture}%
}

\tikzset{tikzborder/.style={line width=1mm,red,double=blue}}

\newcounter{tikzborder}
\newcounter{tikzborderpages}
\newenvironment{tikzborder}[1][]{%
    \medskip\par
    % Allow user to overwrite the used style locally
    \ifx&#1&\else
        \tikzset{tikzborder/.style={#1}}%
    \fi
    \settextarea
    \stepcounter{tikzborder}%
    \tikz[overlay,remember picture] \coordinate (tikzborder-\thetikzborder);% Modified \tikzmark macro
    \zlabel{tikzborder-begin-\thetikzborder}%
    % Test if end-label is at the same page and draw first half of border if not
    \ifnum\zref@extract{tikzborder-begin-\thetikzborder}{abspage}=\zref@extract{tikzborder-end-\thetikzborder}{abspage} \else
        \begin{tikzpicture}[overlay,remember picture]
            \draw [tikzborder]
                let \p0 = (textarea.north west), \p1 = (tikzborder-\thetikzborder), \p2 = (textarea.south east) in
                (\x0-\fboxsep-.5\pgflinewidth,\y2-\fboxsep-.5\pgflinewidth)
                 |-
                (\x2+\fboxsep+.5\pgflinewidth,\ht\strutbox+\fboxsep+.5\pgflinewidth)
                 --
                (\x2+\fboxsep+.5\pgflinewidth,\y2-\fboxsep-.5\pgflinewidth)
                ;
        \end{tikzpicture}%
    % If it spreads over more than two pages:
    \setcounter{tikzborderpages}{\numexpr-\zref@extract{tikzborder-begin-\thetikzborder}{abspage}+\zref@extract{tikzborder-end-\thetikzborder}{abspage}}
    \ifnum\value{tikzborderpages}>1
        \AtBeginShipoutNext{\tikzborderpage}%
    \fi
    \fi
}{%
    \zlabel{tikzborder-end-\thetikzborder}%
    % Test if begin-label is at the same page and draw while border if so
    \ifnum\zref@extract{tikzborder-begin-\thetikzborder}{abspage}=\zref@extract{tikzborder-end-\thetikzborder}{abspage}
        \begin{tikzpicture}[overlay,remember picture]
            \draw [tikzborder]
                let \p0 = (textarea.north west), \p1 = (tikzborder-\thetikzborder), \p2 = (textarea.south east) in
                (\x0-\fboxsep-.5\pgflinewidth,\y1+\ht\strutbox+\fboxsep+.5\pgflinewidth)
                 |-
                (\x2+\fboxsep+.5\pgflinewidth,-\dp\strutbox-\fboxsep-.5\pgflinewidth)
                 |-
                (\x0-\fboxsep-.5\pgflinewidth,\y1+\ht\strutbox+\fboxsep+.5\pgflinewidth)
                 -- cycle
                ;
        \end{tikzpicture}%
    % Otherwise draw second half of border
    \else
        \settextarea
        \begin{tikzpicture}[overlay,remember picture]
            \draw [tikzborder]
                let \p0 = (textarea.north west), \p1 = (tikzborder-\thetikzborder), \p2 = (textarea.south east) in
                (\x0-\fboxsep-.5\pgflinewidth,\y0+\fboxsep+.5\pgflinewidth)
                 |-
                (\x2+\fboxsep+.5\pgflinewidth,-\dp\strutbox-\fboxsep-.5\pgflinewidth)
                 --
                (\x2+\fboxsep+.5\pgflinewidth,\y0+\fboxsep+.5\pgflinewidth)
                ;
        \end{tikzpicture}%
    \fi
    \par\medskip
}

\newcommand{\tikzborderpage}{%
  \settextarea
  \begin{tikzpicture}[overlay,remember picture]
      \draw [tikzborder]
          ([shift={(-\fboxsep-.5\pgflinewidth, \fboxsep+.5\pgflinewidth)}]textarea.north west)
           --
          ([shift={(-\fboxsep-.5\pgflinewidth,-\fboxsep-.5\pgflinewidth)}]textarea.south west)
          ;
      \draw [tikzborder]
          ([shift={( \fboxsep+.5\pgflinewidth, \fboxsep+.5\pgflinewidth)}]textarea.north east)
           --
          ([shift={( \fboxsep+.5\pgflinewidth,-\fboxsep-.5\pgflinewidth)}]textarea.south east)
          ;
  \end{tikzpicture}%
  \addtocounter{tikzborderpages}{-1}%
  \ifnum\value{tikzborderpages}>1
    \AtBeginShipoutNext{\tikzborderpage}%
  \fi
  \vspace{-\baselineskip}% Compensate for the generated extra line at begin of the page. No idea why exactly this happens. Also \baselineskip seems not to be 100% right.
}

\makeatother

\usepackage{lipsum}
\newcommand\xlipsum[1][]{{\let\par\relax\lipsum*[#1]}}

\begin{document}
\begin{tikzborder}
  \xlipsum[1]
\end{tikzborder}

\lipsum[2-4]

\begin{tikzborder}
  \xlipsum[1]
\end{tikzborder}

\lipsum[2-4]

\begin{tikzborder}
  \xlipsum[1-9]
\end{tikzborder}

\lipsum[2-4]

\begin{tikzborder}
  \xlipsum[1-20]
\end{tikzborder}


\end{document}

(由于分辨率低等原因,画面中框架无法完全正确显示。
点击放大

结果

答案2

我在这里的评论中写了一个mdframed例子tikzsetting

需要mdframded v0.7a

\documentclass[parskip=half-]{scrartcl}

\usepackage[%
  style=1,%
  splitbottomskip=0.8cm,splittopskip=0cm,
  innerrightmargin=1cm,innertopmargin=1cm,%
  innerlinewidth=2pt,outerlinewidth=2pt,middlelinewidth=10pt,
  backgroundcolor=red,%
  roundcorner=25pt,
  %leftline=false,
%  rightline=false,
%  %topline=false,
%  bottomline=false
  ]{mdframed}

%example 1
\mdfsetup{%
tikzsetting={draw=yellow,line width=3pt,dashed,dash pattern= on 10pt off 3pt}}

%%example 2
%\mdfsetup{%
%linecolor=blue,middlelinecolor=gray,tikzsetting={line width=2pt,double=blue,draw=red,double distance=3pt,dashed}}

%%example 3
%\mdfsetup{%
%linecolor=blue,middlelinecolor=gray,tikzsetting={dashed,draw=red}}


\usepackage{lipsum}

\begin{document}

\begin{mdframed}
\lipsum[1]
\end{mdframed}

~
%
\begin{mdframed}
\lipsum[1-8]
\end{mdframed}

\end{document}

我希望它能有所帮助。顺便说一句:我认为我以一种简单的方式编写了代码;-)——我是包编写的初学者

示例 1:

显示示例 1

示例 2:

显示示例 2

示例 3:

显示示例 3

相关内容