[Tex/LaTex] Drawing tikz line in the margin for multiple pages

tikz-pgf

Inspired by a code portion found on this site (I can't remember…), I could do the following to draw a line on the first page starting on top:

\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}

What I'd like to do is to extend the rectangle to the end of a long text (so there may be an 'environment' to build and/or a newcommand with a parameter taking into account the text), and to be able to begin exactly at the begining of this text and to end exactly where it ends, even if begining or end is in the middle of the page, AND (tiebraker ;)) without using a box.

Indeed, I know how to do this using for instance mdframed and shifting to the left the left bar… It works well and it's nice but we do know that two breakable/splitable boxes created with framed, mdframed, tcolorbox, etc. can't be nested (even one with another, in the cases I tried at least).
But, that's what I want to do: the line (the big rule in fact) I am drawing with tikz will be used as the container and I will be able to put other breakable/splitable boxes inside it…

Is that possible? Ever made?

EDIT: the inspiration is here: TikZ full page with absolute node positioning.

Best Answer

This uses tikzpagenodes, tikzmark and everypage. Don't forget to run it twice.

I used an environment mostly to make it hard to mess up. OTOH, I forgot to address nested environments.

\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}