在多页边距中绘制 tikz 线

在多页边距中绘制 tikz 线

受到在这个网站上找到的一段代码的启发(我不记得了......),我可以执行以下操作在第一页上从顶部开始画一条线:

\documentclass[a4paper,12pt]{book}
\usepackage{tikz}
\usepackage{etoolbox}
\usepackage{lipsum}

\begin{document}

\thispagestyle{empty}

\begin{tikzpicture}[remember picture,overlay]
    \node (back names) [shape=rectangle,
    fill=black!80, 
    minimum height=\textheight, 
    minimum width=1cm, 
    anchor=north west] 
    at ([yshift=-(1in+\topmargin+\headheight+\headsep)]current page.north west) {};
\end{tikzpicture}

First line.
Second line.
\lipsum

\end{document}

我想要做的是将矩形扩展到长文本的末尾(因此可能有一个要构建的“环境”和/或一个带有参数的新命令考虑到文本),并且能够准确地从这段文本的开头开始,并准确地在它结束的地方结束,即使开始或结束在页面的中间,AND(tiebraker;))无需使用盒子

确实,我知道如何使用例如 mdframed 并将左侧栏向左移动来做到这一点...它运行良好,而且很棒我们确实知道,使用 framed、mdframed、tcolorbox 等创建的两个可破坏/可拆分框不能嵌套(至少在我尝试过的情况下,一个框甚至不能嵌套另一个框)。但是,这就是我想要做的:我用 tikz 绘制的线(实际上是大规则)将用作容器,我将能够将其他可破坏/可拆分框放入其中……

这可能吗?曾经实现过吗?

编辑:灵感在这里:TikZ 整页带绝对节点定位

答案1

这使用 tikzpagenodes、tikzmark 和 everypage。别忘了运行两次。

我使用环境主要是为了避免出错。另一方面,我忘记处理嵌套环境了。

\documentclass[a4paper,12pt]{book}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc,tikzmark}
\usepackage{lipsum}
\usepackage{showframe}
\usepackage{everypage}

\makeatletter
\newcommand{\checkmarkpage}[4]% #1 = tikzmark label, #2 = less, #3 = equal, #4 = greater
{\@ifundefined{save@pt@#1}{#2}{%
  \edef\markid{\csname save@pt@#1\endcsname}%
  \edef\markpage{\csname save@pg@\markid\endcsname}%
  \ifnum\thepage<\markpage\relax #2%
  \else
    \ifnum\thepage=\markpage\relax #3%
    \else #4%
    \fi
  \fi}%
}
\makeatother

\newcounter{outlineid}
\newcounter{outlinedone}

\newenvironment{outline}{\par\tikzmark{begin\theoutlineid}\ignorespaces}%
  {\par\tikzmark{end\theoutlineid}\stepcounter{outlineid}\ignorespaces}

\newcommand{\drawoutline}{\checkmarkpage{begin\theoutlinedone}{}%
  {\begin{tikzpicture}[remember picture,overlay]
    \path ({pic cs:begin\theoutlinedone}-| current page text area.west)
      ++(0pt,\ht\strutbox) coordinate(A);
    \checkmarkpage{end\theoutlinedone}%
      {\path (current page text area.south west) ++(0pt,-\dp\strutbox)
         coordinate(B);}%
      {\path ({pic cs:end\theoutlinedone}-| current page text area.west)
        ++(0pt,\ht\strutbox) coordinate(B);}%
      {}% this should not happen
    \fill[yellow] ($(A) + (-.333em,0pt)$) rectangle ($(B) + (-1cm,0pt)$);
   \end{tikzpicture}}%
  {\begin{tikzpicture}[remember picture,overlay]
    \coordinate (A) at (current page text area.north west);
    \checkmarkpage{end\theoutlinedone}%
      {\path (current page text area.south west) ++(0pt,-\dp\strutbox)
         coordinate(B);}%
      {\path ({pic cs:end\theoutlinedone}-| current page text area.west)
        ++(0pt,\ht\strutbox) coordinate(B);}%
      {}% this should not happen
    \fill[yellow] ($(A) + (-.333em,0pt)$) rectangle ($(B) + (-1cm,0pt)$);
   \end{tikzpicture}}%
  \checkmarkpage{end\theoutlinedone}{}%
    {\stepcounter{outlinedone}\drawoutline}%
    {}% this should not happen
 }
\AddEverypageHook{\drawoutline}

\begin{document}

\newpage 

\thispagestyle{empty}

\lipsum[1]

Next line begins the rule :

\begin{outline}
\lipsum[2]
\end{outline}

Line above ends the rule.

Two on one page:
\begin{outline}
\lipsum[3]
\end{outline}

One on three pages:
\begin{outline}
\lipsum[4-12]
\end{outline}
That's all, folks.

\end{document}

答案2

这是答案的开始。我现在可以从任意一条线到另一条任意线绘制规则在同一页上下一步是找到一种方法来:

1)在页面末尾最后一行之前停止规则;

2)转到下一页(例如当前页+1 ??);

3)重复1)-2)直到文本结束......

当然还有一两件事,因为下面代码中的 \zsavepos{lineend} 没有考虑到这个位置可能是第一页之后的第 1、2、3...x 页!那么如何知道呢?...

对我很重要...): 我使用了 dimtomm(将 pt 中的 dim 转换为 mm)代码部分中的一段代码(dimwithoutpt),但我不太理解 dimexpr 的语法(我读过 etex-man,但是……嗯!)。如果有人能向我解释代码的读取方式,那就太好了 :-)。

也许有更简洁的方法来转换和设置 \beg 和 \portionheight,但我对这种操作一点也不熟悉......

\documentclass[a4paper,12pt]{book}
\usepackage{tikz}
\usepackage{etoolbox}
\usepackage{lipsum}
\usepackage{showframe}
\usepackage{layout}
\usepackage{zref-savepos}

\makeatletter
\newcommand\dimwithoutpt[1]{%
    \strip@pt\dimexpr 1\dimexpr#1\relax\relax%
}
\makeatother

\newlength\beg
\newlength\portionheight

\begin{document}
\layout{}

\newpage 

\thispagestyle{empty}

\lipsum[1]

Next line begins the rule :

\zsavepos{linedeb}Begining of my new section.

\setlength{\beg}{dimwithoutpt{\paperheight-\zposy{linedeb}sp}pt}

\lipsum[2]\zsavepos{lineend} 
\setlength{\portionheight}{\dimwithoutpt{\zposy{linedeb}sp-\zposy{lineend}sp}pt}

\begin{tikzpicture}[remember picture,overlay]
    \node (back names) [shape=rectangle, fill=yellow, minimum height=\portionheight, minimum width=1cm, anchor=north west] at ([yshift=-\beg,xshift=1in+\oddsidemargin-1cm]current page.north west) {};
\end{tikzpicture}
Line above ends the rule.

And next : 

\lipsum[3]

\end{document}

相关内容