3

Combining this solution to draw braces with tikzmarks, with this to make them go across page boundaries, presents me with an interesting problem: It won't print the vertical part on the first page if tikzmark sits in an environment.
Edit: I'm using code from the latest update to the tikzmark package that includes the \iftikzmarkoncurrentpage macro, which I added below too.

% !TEX TS-program = xelatexmk
\documentclass{article}
\usepackage[paperwidth=3in,paperheight=1in]{geometry}
\usepackage{tikz}
\usepackage{tikzpagenodes}
\usetikzlibrary{tikzmark}
\newcounter{tikzmarklines}\setcounter{tikzmarklines}{0} % 

% The following code provides the iftikzmarkoncurrentpage macro
\makeatletter    
\newif\iftikzmark@
\renewcommand\iftikzmark[3]{%
    \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
      #3%
    }{%
      #2%
    }%
}%

\newcommand\iftikzmarkexists[1]{%
  \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
    \tikzmark@false%
  }{%
    \tikzmark@true%
  }%
  \iftikzmark@
}%

\newcommand\iftikzmarkonpage[2]{%
  \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
    \tikzmark@false
  }{%
    \@ifundefined{save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname}{%
      \tikzmark@false
    }{%
      \ifnum\csname save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname\endcsname=#2\relax%
      \tikzmark@true
      \else
      \tikzmark@false
      \fi
    }%
  }%
  \iftikzmark@
}

\newcommand\iftikzmarkoncurrentpage[1]{%
  \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
    \tikzmark@false
  }{%
    \@ifundefined{save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname}{%
      \tikzmark@false
    }{%
      \ifnum\csname save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname\endcsname=\the\value{page}\relax%
      \tikzmark@true
      \else
      \tikzmark@false
      \fi
    }%
  }%
  \iftikzmark@
}
\makeatother

\tikzset{
  next page=below,
  brace/.style n args={2}{insert path={%
  ([xshift=0.15em,yshift=0.1pt+.5ex]#1) -- 
  ([xshift=-0.3pt,yshift=0.1pt+.5ex]#1) -- 
  ([xshift=-0.3pt,yshift=-0.1pt+.5ex]#2) -- 
  ([xshift=0.15em,yshift=-0.1pt+.5ex]#2) -- 
  ([xshift=0.15em,yshift=0.1pt+.5ex]#2) --
  ([xshift=0.3pt,yshift=0.1pt+.5ex]#2) --
  ([xshift=0.3pt,yshift=-0.1pt+.5ex]#1) --
  ([xshift=0.15em,yshift=-0.1pt+.5ex]#1) --
  cycle}}}

\newif\iffirstmark

\newcommand{\linestart}{%
  \stepcounter{tikzmarklines}%
  \tikzmark{a\thetikzmarklines}%
  \firstmarktrue
  \iftikzmarkoncurrentpage{b\thetikzmarklines}%
  \else
  \begin{tikzpicture}[remember picture,overlay,next page=below]%
  \clip (current page text area.south west) rectangle (current page text area.north east);
  \fill[overlay,brace={pic cs:a\thetikzmarklines}{pic cs:b\thetikzmarklines}];
  \end{tikzpicture}%
  \fi
}

\newcommand{\linefinish}{%
  \iffirstmark
  \tikzmark{b\thetikzmarklines}%
  \firstmarkfalse
  \fi
  \begin{tikzpicture}[remember picture,overlay]%
  \clip (current page text area.south west) rectangle (current page text area.north east);
  \fill[overlay,brace={pic cs:a\thetikzmarklines}{0,0}];
  \end{tikzpicture}%
  }

\begin{document} 
% This works fine:
Text \linestart text text
\newpage
Text text \linefinish text

% But not this
\begin{center} Text \linestart text text \end {center}
\newpage 
\begin{center} Text text \linefinish text \end {center}
\end{document}

Only the little hook is printed on the second page, but not the vertical line to page 3.

enter image description here

Any ideas?

  • Do you use a special version of tikzmark? I get an error ! Undefined control sequence. \linestart ...stmarktrue \iftikzmarkoncurrentpage {b\thetikzmarklines }\else.. – marmot Apr 11 at 9:28
  • 1
    @marmot Oops, yes, I do ... I used the last one from github because Andrew had recently added the \iftikzmarkoncurrentpage command which is used here. – jan Apr 11 at 9:29
  • OK, I cannot run it but I suspect it may have not to do with the environment but with the fact that the if's get confused. That is, did you try to have the tikzmarks in the center environments first? – marmot Apr 11 at 9:34
  • 1
    @marmot You mean putting the environment first? Yes, I tried that too, but same result :( – jan Apr 11 at 9:35
1

You need to make the if global: \global\firstmarktrue and, as you pointed out, \global\firstmarkfalse.

% !TEX TS-program = xelatexmk
\documentclass{article}
\usepackage[paperwidth=3in,paperheight=1in]{geometry}
\usepackage{tikz}
\usepackage{tikzpagenodes}
\usetikzlibrary{tikzmark}
\newcounter{tikzmarklines}\setcounter{tikzmarklines}{0} % 

% The following code provides the iftikzmarkoncurrentpage macro
\makeatletter    
\newif\iftikzmark@
\renewcommand\iftikzmark[3]{%
    \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
      #3%
    }{%
      #2%
    }%
}%

\newcommand\iftikzmarkexists[1]{%
  \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
    \tikzmark@false%
  }{%
    \tikzmark@true%
  }%
  \iftikzmark@
}%

\newcommand\iftikzmarkonpage[2]{%
  \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
    \tikzmark@false
  }{%
    \@ifundefined{save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname}{%
      \tikzmark@false
    }{%
      \ifnum\csname save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname\endcsname=#2\relax%
      \tikzmark@true
      \else
      \tikzmark@false
      \fi
    }%
  }%
  \iftikzmark@
}

\newcommand\iftikzmarkoncurrentpage[1]{%
  \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
    \tikzmark@false
  }{%
    \@ifundefined{save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname}{%
      \tikzmark@false
    }{%
      \ifnum\csname save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname\endcsname=\the\value{page}\relax%
      \tikzmark@true
      \else
      \tikzmark@false
      \fi
    }%
  }%
  \iftikzmark@
}
\makeatother

\tikzset{
  next page=below,
  brace/.style n args={2}{insert path={%
  ([xshift=0.15em,yshift=0.1pt+.5ex]#1) -- 
  ([xshift=-0.3pt,yshift=0.1pt+.5ex]#1) -- 
  ([xshift=-0.3pt,yshift=-0.1pt+.5ex]#2) -- 
  ([xshift=0.15em,yshift=-0.1pt+.5ex]#2) -- 
  ([xshift=0.15em,yshift=0.1pt+.5ex]#2) --
  ([xshift=0.3pt,yshift=0.1pt+.5ex]#2) --
  ([xshift=0.3pt,yshift=-0.1pt+.5ex]#1) --
  ([xshift=0.15em,yshift=-0.1pt+.5ex]#1) --
  cycle}}}

\newif\iffirstmark

\newcommand{\linestart}{%
  \stepcounter{tikzmarklines}%
  \tikzmark{a\number\value{tikzmarklines}}%
  \global\firstmarktrue
  \iftikzmarkoncurrentpage{b\number\value{tikzmarklines}}%
  \else
  \begin{tikzpicture}[remember picture,overlay,next page=below]%
  \clip (current page text area.south west) rectangle (current page text area.north east);
  \fill[overlay,brace={pic cs:a\number\value{tikzmarklines}}{pic cs:b\number\value{tikzmarklines}}];
  \end{tikzpicture}%
  \fi
}

\newcommand{\linefinish}{%
  \iffirstmark
  \tikzmark{b\number\value{tikzmarklines}}%
  \global\firstmarkfalse
  \fi
  \begin{tikzpicture}[remember picture,overlay]%
  \clip (current page text area.south west) rectangle (current page text area.north east);
  \fill[overlay,brace={pic cs:a\number\value{tikzmarklines}}{0,0}];
  \end{tikzpicture}%
  }

\begin{document} 
% But not this
\begin{center} Text \linestart text text \end{center}
\newpage 
\begin{center} Text text \linefinish text \end{center}


% This works fine:
Text \linestart text text
\newpage
Text text \linefinish text

\end{document}

enter image description here

  • Awesome. Thanks so much! Would \firstmarkfalse also have to be global? – jan Apr 11 at 10:16
  • 1
    @jan Yes. Good catch! – marmot Apr 11 at 10:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.