3

I'm writing a double-paged document where I'm using pdfpages to insert a pdf on every other page, so that if you read it like a book, the page on the right shows the pdf, while the one on the left is reserved for comments. For these comments, I would like to draw some lines, or arrows, or boxes, or something like that, that connect the comments to stuff in the pdf. I thought I would probably have to use TikZ for that, but I have no idea how, as I have never used that before. Is something like that even possible?

I found this post, which is similar, but too complex for me to understand what's going on.

3
  • Hello! It will help to produce a useful answer if you post some code that produces a document as described, with some pdf pages inserted and comments on the opposite page. Commented Aug 5, 2022 at 17:23
  • 1
    Somewhat related: tex.stackexchange.com/questions/363957/… Commented Aug 5, 2022 at 18:56
  • @SimonDispa that's fair. But I wasn't fast enough for Jasper Habicht's answer.
    – mapf
    Commented Aug 6, 2022 at 9:11

1 Answer 1

4

As I understood your question, you have two pages next to each other, one on the right where you include a page from some PDF file, and one on the left where you want to state annotations. Then, you want to draw lines going from the left to the right, crossing the page boundaries.

With the following approach that works a bit like tikzmarks, you can use the macro \annotline to define the coordinate on the next page (the upper left corner of the page is the origin, unit is centimeters) where you want to draw a line to. The macro will then draw a line starting where you placed the macro that goes towards the right margin of the page where it turns up or down until it reaches the height of the coordinate on the next page where it turns to the right again. You can use the macro \annotlinebreakdist to define the distance from the right margin of the page to the vertical part of the line.

On the next page, you can use the macro \printannotlines to draw the remaining part of the lines that start form the left margin of the page and go to the relevant coordinate. The macro automatically draws all the lines that haven't been finished until then.

You can style the line using TikZ styles. In case the lines overlap, you can use the second optional argument to shift the vertical part of the line to the right or left. Using the first optional parameter, you can shift the starting point of the line to the left or right.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\tikzset{
    annotline/.style={
        very thick, red
    },
    annotline start/.style={
    },
    annotline end/.style={
        ->
    }
}

\ExplSyntaxOn

\dim_new:N \l_annotline_breakdist_dim
\dim_set:Nn \l_annotline_breakdist_dim { 1cm }

\NewDocumentCommand{\annotlinebreakdist}{ m }{
    \dim_set:Nn \l_annotline_breakdist_dim { #1 }
}

\clist_new:N \l_annotline_allxpos_clist
\clist_new:N \l_annotline_allypos_clist
\int_new:N \l_annotline_currid_int
\int_new:N \l_annotline_lastid_int

\NewDocumentCommand{\annotline}{ O{0pt} O{0pt} m m }{%
    \clist_put_right:Nn \l_annotline_allxpos_clist { #3 }
    \clist_put_right:Nn \l_annotline_allypos_clist { #4 }
    \int_incr:N \l_annotline_currid_int
    \begin{tikzpicture}[remember~picture, overlay] 
        \coordinate (annotline-\int_use:N\l_annotline_currid_int -start) at 
            ([xshift=#1,yshift=.5ex]0,0);
        \coordinate (annotline-\int_use:N\l_annotline_currid_int -start-break) at 
            ([xshift={-1*\dim_use:N\l_annotline_breakdist_dim+#2}]current~page.east);
        \coordinate (annotline-\int_use:N\l_annotline_currid_int -start-margin) at 
            ([shift={(0,-1*#4)}]current~page.north~east);
        \draw[annotline, annotline~start] 
            (annotline-\int_use:N\l_annotline_currid_int -start) --
            (annotline-\int_use:N\l_annotline_currid_int -start -| annotline-\int_use:N\l_annotline_currid_int -start-break) |-
            (annotline-\int_use:N\l_annotline_currid_int -start-margin);
    \end{tikzpicture}
}

\dim_new:N \l_annotline_currxpos_dim
\dim_new:N \l_annotline_currypos_dim

\NewDocumentCommand{\annotlineend}{ m }{%
    \dim_set:Nn \l_annotline_currxpos_dim { \clist_item:Nn \l_annotline_allxpos_clist #1 cm }
    \dim_set:Nn \l_annotline_currypos_dim { \clist_item:Nn \l_annotline_allypos_clist #1 cm }
    \begin{tikzpicture}[remember~picture, overlay]
        \coordinate (annotline-#1-end-margin) at 
            ([shift={(0,-1*\int_use:N\l_annotline_currypos_dim)}]current~page.north~west);
        \coordinate (annotline-#1-end) at 
            ([shift={(\dim_use:N\l_annotline_currxpos_dim,-1*\dim_use:N\l_annotline_currypos_dim)}]current~page.north~west);
        \draw[annotline, annotline~end] 
            (annotline-#1-end-margin) --
            (annotline-#1-end);
    \end{tikzpicture}
}

\NewDocumentCommand{\printannotlines}{}{%
    \int_incr:N \l_annotline_lastid_int
    \foreach \i in {\int_use:N\l_annotline_lastid_int,...,\int_use:N\l_annotline_currid_int} {
        \annotlineend{\i}
    }
    \int_set:Nn \l_annotline_lastid_int \l_annotline_currid_int
}

\ExplSyntaxOff

\begin{document}

\annotlinebreakdist{2cm}

Some very interesting thing \annotline[0pt][10pt]{8}{5}

Some other interesting thing \annotline[0pt][-10pt]{12}{10}

\vspace{10cm}

Yet another interesting thing \annotline{16}{7.5}

\newpage

\noindent
\includegraphics[width=\textwidth]{example-image-a}

\printannotlines

\newpage

Again some very interesting thing \annotline{10}{10}

\newpage

\noindent
\includegraphics[width=\textwidth]{example-image-a}

\printannotlines

\end{document}

enter image description here


If you want a vertical line alongside the comment, you might want to use a node which contains the comment:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\tikzset{
    annotline/.style={
        very thick, red
    },
    annotline start/.style={
    },
    annotline end/.style={
        ->
    },
    annotline box/.style={
        inner sep=0pt,
        text width=5cm,
    }
}

\ExplSyntaxOn

\dim_new:N \l_annotline_breakdist_dim
\dim_set:Nn \l_annotline_breakdist_dim { 1cm }

\NewDocumentCommand{\annotlinebreakdist}{ m }{
    \dim_set:Nn \l_annotline_breakdist_dim { #1 }
}

\clist_new:N \l_annotline_allxpos_clist
\clist_new:N \l_annotline_allypos_clist
\int_new:N \l_annotline_currid_int
\int_new:N \l_annotline_lastid_int

\NewDocumentEnvironment{annotlinebox}{ O{0pt} O{0pt} m m +b }{%
    \clist_gput_right:Nn \l_annotline_allxpos_clist { #3 }
    \clist_gput_right:Nn \l_annotline_allypos_clist { #4 }
    \int_gincr:N \l_annotline_currid_int
    \begin{tikzpicture}[remember~picture]
        \node[annotline~box] (annotline-\int_use:N\l_annotline_currid_int -box) at (0,0) { { #5 } };
        \begin{scope}[overlay]
            \coordinate (annotline-\int_use:N\l_annotline_currid_int -start) at 
                ([xshift=#1]annotline-\int_use:N\l_annotline_currid_int -box.north~east);
            \coordinate (annotline-\int_use:N\l_annotline_currid_int -start-break) at 
                ([xshift={-1*\dim_use:N\l_annotline_breakdist_dim+#2}]current~page.east);
            \coordinate (annotline-\int_use:N\l_annotline_currid_int -start-margin) at 
                ([shift={(0,-1*#4)}]current~page.north~east);
            \draw[annotline, annotline~start] 
                (annotline-\int_use:N\l_annotline_currid_int -box.south~east -| annotline-\int_use:N\l_annotline_currid_int -start) --
                (annotline-\int_use:N\l_annotline_currid_int -start) --
                (annotline-\int_use:N\l_annotline_currid_int -start -| annotline-\int_use:N\l_annotline_currid_int -start-break) |-
                (annotline-\int_use:N\l_annotline_currid_int -start-margin);
        \end{scope}
    \end{tikzpicture}
}{}

\dim_new:N \l_annotline_currxpos_dim
\dim_new:N \l_annotline_currypos_dim

\NewDocumentCommand{\annotlineend}{ m }{%
    \dim_set:Nn \l_annotline_currxpos_dim { \clist_item:Nn \l_annotline_allxpos_clist #1 cm }
    \dim_set:Nn \l_annotline_currypos_dim { \clist_item:Nn \l_annotline_allypos_clist #1 cm }
    \begin{tikzpicture}[remember~picture, overlay]
        \coordinate (annotline-#1-end-margin) at 
            ([shift={(0,-1*\int_use:N\l_annotline_currypos_dim)}]current~page.north~west);
        \coordinate (annotline-#1-end) at 
            ([shift={(\dim_use:N\l_annotline_currxpos_dim,-1*\dim_use:N\l_annotline_currypos_dim)}]current~page.north~west);
        \draw[annotline, annotline~end] 
            (annotline-#1-end-margin) --
            (annotline-#1-end);
    \end{tikzpicture}
}

\NewDocumentCommand{\printannotlines}{}{%
    \int_incr:N \l_annotline_lastid_int
    \foreach \i in {\int_use:N\l_annotline_lastid_int,...,\int_use:N\l_annotline_currid_int} {
        \annotlineend{\i}
    }
    \int_set:Nn \l_annotline_lastid_int \l_annotline_currid_int
}

\ExplSyntaxOff

\begin{document}

\annotlinebreakdist{2cm}

\begin{annotlinebox}{8}{5}
    Some very interesting thing
\end{annotlinebox}

\vspace{10cm}

\begin{annotlinebox}{12}{10}
    Some other interesting thing \\
    which is a bit longer \\
    than the other
\end{annotlinebox}

\newpage

\noindent
\includegraphics[width=\textwidth]{example-image-a}

\printannotlines

\end{document}

enter image description here

12
  • 1
    @mapf I wasn't sure whether this would suit your needs. I just corrected a minor flaw in the code (It had four lines which were remains from prior testing but which are not necessary actually) so I updated the answer. Commented Aug 6, 2022 at 9:19
  • 1
    @mapf I added a variation to my answer that uses a node to contain the comment. Using this approach, it is easy to append a vertical line to the side of the comment. Commented Nov 23, 2022 at 10:39
  • 1
    @mapf Between \ExplSyntaxOn and \ExplSyntaxOff, spaces are ignored. But some TikZ options, such as rounded corners, need a space. You can use ~ to insert a space inside the expl3 syntax block since ~ will be converted to a space. Commented Nov 24, 2022 at 12:40
  • 1
    @mapf Sorry, but I cannot reproduce this problem with my code above. It is probably a scoping issue. Try to replace \int_incr:N \l_annotline_lastid_int by \int_gincr:N \l_annotline_lastid_int and \int_set:Nn \l_annotline_lastid_int \l_annotline_currid_int by \int_gset:Nn \l_annotline_lastid_int \l_annotline_currid_int in the defintion for the \printannotlines macro to set the two counters globally. If this does not help, I suggest that you ask a new question and show your current code. Commented Nov 24, 2022 at 16:05
  • 1
    Just to let you know: your suggestion works! Thanks!
    – mapf
    Commented Nov 25, 2022 at 9:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .