0

After page-break my node (string) gets lost. Only at the first page my node "100" is shown. This code contains parts from @skillmon @ulrike fischer @saso Thank you at this point. I know i should post a shorter code but in my opinion i can not make it shorter otherwise it does not work anymore. Thank you in advance.

\documentclass[11pt,a4paper,titlepage,bibliography=totoc,numbers=noenddot,abstract=on,multi,dvipsnames,svgnames,x11names]{scrreprt}

\usepackage{storebox}
\usepackage[edges]{forest}
\usepackage{adjustbox}

%Zeilenumbruch in der tikz Umgebung!
% addaswyd o gôd Sašo Živanović: http://tex.stackexchange.com/a/296771/
\def\hiddenparcommand{\par}
\newcommand\otherhiddenparcommand{\par\noindent}
\newcommand\hiddencommacommand{, }
\forestset{%
    declare keylist register={split here ids},% the list of nodes to split the tree at
    split here ids={},
    declare keylist register={split here interjects},% the list of comments to put in between the tree parts
    split here interjects={},
    declare keylist={split here auto siblings}{},% a list to hold the siblings which need edge restoration
    declare toks register=split here toks,
    declare dimen register=tmpdima,
    tmpdima'=0pt,
    declare dimen register=tmpdimb,
    tmpdimb'=0pt,
    declare dimen register=tmpdimc,
    tmpdimc'=0pt,
    to widest/.style={
        tikz+={\path (\forestregister{tempdima}, \forestoption{y}) -- (\forestregister{tempdimb}, \forestoption{y});},
    },
    hide commas/.style={%
        split here toks+={\hiddencommacommand},
        split here toks+={#1},
    },
    split dir tree pre/.style={%
        label={[text=gray, anchor=north, font=\scriptsize]below:{[cont.]}{}},
    },
    split dir tree post/.style={%
        label={[font=\scriptsize, anchor=south, text=gray]above:{[cont.]}{}},
    },
    split dir tree auto post/.style={% this gets applied to the first node after a break
        split dir tree post,
        tempkeylistc'={},
        tmpdimb/.option=y,
        for nodewalk={
            while={
                > ORw2+d _+d < On=! & {y}{tmpdimb}{##2-##1} {\textheight-#1} {n'}{1}%
            }{
                next,
                tempkeylistc/.option=name
            }%
        }{},
        % save the list
        split here auto siblings/.register=tempkeylistc,
        tikz+/.process={% this tries to redraw the edges to the following siblings
            OOw2{edge}{id}%
            {%
                \path [##1] (!u.parent anchor |- .north) ++(\forestregister{folder indent},1ex) coordinate (before ##2) |- (.child anchor);
                \edef\tempa{\foresteoption{split here auto siblings}}
                \foreach \i in \tempa \path [##1] (before ##2) |- ({forest cs:\i.child anchor});
            }%
        },
    },
    split dir tree/.code={%
        \forestset{%
            draw tree stage/.style={
                for root'={
                    tempdima/.min={%
                        >OOw2+d{x}{min x}{####1+####2}%
                    }{tree},
                    tempdimb/.max={%
                        >OOw2+d{x}{max x}{####1+####2}%
                    }{tree},
                    for tree={%
                        to widest,
                    },
                },
                tempcountb'=-1,
                do until={%
                    strequal((split_here_ids),"")
                }{%
                    tempkeylistb'={},
                    tempkeylista'={},
                    split register={split here ids}{,}{tempcounta,tempkeylistb+},
                    split register={split here interjects}{,}{temptoksa,tempkeylista+},
                    split here ids'/.register=tempkeylistb,
                    split here interjects'/.register=tempkeylista,
                    % Sašo Živanović: http://chat.stackexchange.com/transcript/message/28484520#28484520
                    for nodewalk={%
                        draw tree processing order/.style={%
                            filter={tree}{> ORw+n< OR> & {id}{tempcounta}{########1+1}{id}{tempcountb}}%
                        }%
                    }{},
                    for root'={draw tree},
                    TeX/.process={Rw{temptoksa}{\otherhiddenparcommand ####1\hiddenparcommand}},
                    tempcountb'/.register=tempcounta,
                },
                for nodewalk={%
                    draw tree processing order/.style={%
                        filter={tree}{>OR>{id}{tempcountb}}%
                    }%
                }{},
                for root'={draw tree},
            },
        }%
    },
    split dir here auto/.style n args=2{%
        split dir tree pre,
        !next node.split dir tree auto post=#2,
        split here ids+/.option=id,
        %     !next node.split resume here ids+/.option=id,
        split={#1}{,}{split here toks,hide commas},
        split here interjects/.register=split here toks,
    },
    split dir tree auto/.style={%
        split dir tree,
        before drawing tree={%
            tempdima/.max={y}{tree},
            tempdimc/.register=tempdima,
            tempdimd/.min={y}{tree},
            tempdima-/.register=tempdimd,
            tempdimb'=\textheight,
            tmpdima'=10ex,
            tmpdimc'=\pagetotal,
            while={%
                >RR>{tempdima}{tempdimb}%
            }{%
                for nodewalk={%
                    root',
                    until={%
                        > ROw2+d RRw2+d > {tempdimc}{y}{##1-##2} {tmpdima}{tmpdimc}{\textheight-##2-##1}%
                    }{next node},
                    previous node,
                    split dir here auto/.process={R_w2{tmpdima}{continued}{{##2}{##1}}},
                    next node,
                    tempdima/.option=y,
                    tempdimc/.register=tempdima,
                    tempdima-/.register=tempdimd,
                    tmpdima'=15ex,
                    tmpdimc'=0pt
                }{},
            },
        },
    },
}
%Zeilenumbruch in der tikz Umgebung! Ende

\usepackage{xparse}
\ExplSyntaxOn
\box_new:N \l_helmutW_box
\cs_new_protected:Npx \helmutW_replace_verb_newline:Nn #1 #2
  {
    \tl_replace_all:Nnn #1 { \char_generate:nn { 13 } { 12 } } { #2 }
  }
\cs_new_protected:Npx \helmutW_replace_verb_newline_newline:Nn #1 #2
  {
    \tl_replace_all:Nnn #1
      { \char_generate:nn { 13 } { 12 } \char_generate:nn { 13 } { 12 } } { #2 }
  }
\cs_new_protected:Npn \helmutW_process_verb_newline:nnn #1 #2 #3
  {
    \tl_set:Nn \ProcessedArgument { #3 }
    \helmutW_replace_verb_newline_newline:Nn \ProcessedArgument { #2 }
    \helmutW_replace_verb_newline:Nn \ProcessedArgument { #1 }
  }
\NewDocumentCommand \AutoSplittedTree
  {
    s
    O{ for~tree = { folder, grow'=0, fit=band, } }
    >{ \helmutW_process_verb_newline:nnn { ~ } { ~ \par } } +v
  }
  {
    \par
    \IfBooleanTF { #1 }
      { \iftrue }
      {
        \vbox_set:Nn \l_helmutW_box { \helmutW_tree:n { #2, #3 } }
        \dim_compare:nNnTF { \box_ht:N \l_helmutW_box } >
          { \dim_min:nn { \pagegoal-\pagetotal } { \textheight } }
          {
            \iftrue
          }
          {
            \box_use:N \l_helmutW_box
            \iffalse
          }
      }
      \helmutW_tree:n { #2, split~dir~tree~auto, #3 }
    \fi
  }
\cs_new_protected:Npn \helmutW_tree:n #1
  {
    \scantokens
      {
        \begin{forest}
          #1
        \end{forest}%
      }
  }
\ExplSyntaxOff

\begin{document}    
\AutoSplittedTree
{
[ XYZ
[ XYZ
[ XYZ,edge label={node[pos=0.75,above]{Too}}
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{4}} ]
]
]
]
}
\end{document}
1
  • @Ulrike Fischer if you have any ideas I would be very happy
    – Lin404
    Oct 8, 2018 at 12:26

1 Answer 1

2

The edges of nodes on a non-first page are not drawn using the normal Forest's edge drawing mechanism. This is because the parent of those nodes is not drawn there. The tree-splitting code solves the issue by drawing those edges manually, in split dir tree auto post style, more precisely, in the \foreach ... \path ... line within that style. While that line specifies to use the edge options of the node (.process handler puts the value of edge into ##1), it does not tell TikZ to draw the edge label (see the default value of edge path option, manual 3.7.3).

So, in principle, adding ##3 (set to edge label by .process) to the end of the \path should solve the issue.

    tikz+/.process={% this tries to redraw the edges to the following siblings
        OOOw3{edge}{id}{edge label}%
        {%
            \path [##1] (!u.parent anchor |- .north) ++(\forestregister{folder indent},1ex) coordinate (before ##2) |- (.child anchor)##3;
            \edef\tempa{\foresteoption{split here auto siblings}}
            \foreach \i in \tempa \path [##1] (before ##2) |- ({forest cs:\i.child anchor})##3
        }%
    },

However, there is an additional problem with split dir tree auto post. The style actually applies the edge (and edge label) of the last node on the first page to all edges on the second page. The code below fixes this issue as well.

\documentclass[11pt,a4paper,titlepage,bibliography=totoc,numbers=noenddot,abstract=on,multi,dvipsnames,svgnames,x11names]{scrreprt}

\usepackage{storebox}
\usepackage[edges]{forest}
\usepackage{adjustbox}

%Zeilenumbruch in der tikz Umgebung!
% addaswyd o gôd Sašo Živanović: http://tex.stackexchange.com/a/296771/
\def\hiddenparcommand{\par}
\newcommand\otherhiddenparcommand{\par\noindent}
\newcommand\hiddencommacommand{, }
\forestset{%
    declare keylist register={split here ids},% the list of nodes to split the tree at
    split here ids={},
    declare keylist register={split here interjects},% the list of comments to put in between the tree parts
    split here interjects={},
    %declare keylist={split here auto siblings}{},% a list to hold the siblings which need edge restoration
    declare toks register=split here toks,
    declare dimen register=tmpdima,
    tmpdima'=0pt,
    declare dimen register=tmpdimb,
    tmpdimb'=0pt,
    declare dimen register=tmpdimc,
    tmpdimc'=0pt,
    to widest/.style={
        tikz+={\path (\forestregister{tempdima}, \forestoption{y}) -- (\forestregister{tempdimb}, \forestoption{y});},
    },
    hide commas/.style={%
        split here toks+={\hiddencommacommand},
        split here toks+={#1},
    },
    split dir tree pre/.style={%
        label={[text=gray, anchor=north, font=\scriptsize]below:{[cont.]}{}},
    },
    split dir tree post/.style={%
        label={[font=\scriptsize, anchor=south, text=gray]above:{[cont.]}{}},
    },
    split dir tree auto post/.style={% this gets applied to the first node after a break
        split dir tree post,
        tempkeylistc'={},
        tmpdimb/.option=y,
        for nodewalk={
            while={
                > ORw2+d _+d < On=! & {y}{tmpdimb}{##2-##1} {\textheight-#1} {n'}{1}%
            }{
                next,
                tempkeylistc/.option=name
            }%
        }{},
        % save the list
        %split here auto siblings/.register=tempkeylistc,
        tikz+={\path(!u.parent anchor |- .north) ++(\forestregister{folder indent},1ex) coordinate (before split) |- (.child anchor);},
        split register={tempkeylistc}{,}{edge in tikz},
    },
    edge in tikz/.style={
      tikz+/.process=OOw2{#1.edge}{#1.edge label}{%
        \path [##1] (before split) |- (#1.child anchor)##2;
      },
    },
    split dir tree/.code={%
        \forestset{%
            draw tree stage/.style={
                for root'={
                    tempdima/.min={%
                        >OOw2+d{x}{min x}{####1+####2}%
                    }{tree},
                    tempdimb/.max={%
                        >OOw2+d{x}{max x}{####1+####2}%
                    }{tree},
                    for tree={%
                        to widest,
                    },
                },
                tempcountb'=-1,
                do until={%
                    strequal((split_here_ids),"")
                }{%
                    tempkeylistb'={},
                    tempkeylista'={},
                    split register={split here ids}{,}{tempcounta,tempkeylistb+},
                    split register={split here interjects}{,}{temptoksa,tempkeylista+},
                    split here ids'/.register=tempkeylistb,
                    split here interjects'/.register=tempkeylista,
                    % Sašo Živanović: http://chat.stackexchange.com/transcript/message/28484520#28484520
                    for nodewalk={%
                        draw tree processing order/.style={%
                            filter={tree}{> ORw+n< OR> & {id}{tempcounta}{########1+1}{id}{tempcountb}}%
                        }%
                    }{},
                    for root'={draw tree},
                    TeX/.process={Rw{temptoksa}{\otherhiddenparcommand ####1\hiddenparcommand}},
                    tempcountb'/.register=tempcounta,
                },
                for nodewalk={%
                    draw tree processing order/.style={%
                        filter={tree}{>OR>{id}{tempcountb}}%
                    }%
                }{},
                for root'={draw tree},
            },
        }%
    },
    split dir here auto/.style n args=2{%
        split dir tree pre,
        !next node.split dir tree auto post=#2,
        split here ids+/.option=id,
        %     !next node.split resume here ids+/.option=id,
        split={#1}{,}{split here toks,hide commas},
        split here interjects/.register=split here toks,
    },
    split dir tree auto/.style={%
        split dir tree,
        before drawing tree={%
            tempdima/.max={y}{tree},
            tempdimc/.register=tempdima,
            tempdimd/.min={y}{tree},
            tempdima-/.register=tempdimd,
            tempdimb'=\textheight,
            tmpdima'=10ex,
            tmpdimc'=\pagetotal,
            while={%
                >RR>{tempdima}{tempdimb}%
            }{%
                for nodewalk={%
                    root',
                    until={%
                        > ROw2+d RRw2+d > {tempdimc}{y}{##1-##2} {tmpdima}{tmpdimc}{\textheight-##2-##1}%
                    }{next node},
                    previous node,
                    split dir here auto/.process={R_w2{tmpdima}{continued}{{##2}{##1}}},
                    next node,
                    tempdima/.option=y,
                    tempdimc/.register=tempdima,
                    tempdima-/.register=tempdimd,
                    tmpdima'=15ex,
                    tmpdimc'=0pt
                }{},
            },
        },
    },
}
%Zeilenumbruch in der tikz Umgebung! Ende

\usepackage{xparse}
\ExplSyntaxOn
\box_new:N \l_helmutW_box
\cs_new_protected:Npx \helmutW_replace_verb_newline:Nn #1 #2
  {
    \tl_replace_all:Nnn #1 { \char_generate:nn { 13 } { 12 } } { #2 }
  }
\cs_new_protected:Npx \helmutW_replace_verb_newline_newline:Nn #1 #2
  {
    \tl_replace_all:Nnn #1
      { \char_generate:nn { 13 } { 12 } \char_generate:nn { 13 } { 12 } } { #2 }
  }
\cs_new_protected:Npn \helmutW_process_verb_newline:nnn #1 #2 #3
  {
    \tl_set:Nn \ProcessedArgument { #3 }
    \helmutW_replace_verb_newline_newline:Nn \ProcessedArgument { #2 }
    \helmutW_replace_verb_newline:Nn \ProcessedArgument { #1 }
  }
\NewDocumentCommand \AutoSplittedTree
  {
    s
    O{ for~tree = { folder, grow'=0, fit=band, } }
    >{ \helmutW_process_verb_newline:nnn { ~ } { ~ \par } } +v
  }
  {
    \par
    \IfBooleanTF { #1 }
      { \iftrue }
      {
        \vbox_set:Nn \l_helmutW_box { \helmutW_tree:n { #2, #3 } }
        \dim_compare:nNnTF { \box_ht:N \l_helmutW_box } >
          { \dim_min:nn { \pagegoal-\pagetotal } { \textheight } }
          {
            \iftrue
          }
          {
            \box_use:N \l_helmutW_box
            \iffalse
          }
      }
      \helmutW_tree:n { #2, split~dir~tree~auto, #3 }
    \fi
  }
\cs_new_protected:Npn \helmutW_tree:n #1
  {
    \scantokens
      {
        \begin{forest}
          #1
        \end{forest}%
      }
  }
\ExplSyntaxOff

%\usepackage{trace-pgfkeys}
\begin{document}    
\AutoSplittedTree
{
[ XYZ1
[ XYZ2
[ XYZ3,edge label={node[pos=0.75,above]{Too}}
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ A,before computing xy={l=30pt},edge=red,edge label={node[pos=0.75,above]{400}}]
[ A,before computing xy={l=30pt},edge=blue,edge label={node[pos=0.75,above]{300}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{200}}]
[ A,before computing xy={l=30pt},edge label={node[pos=0.75,above]{100}}]
[ XYZ3,edge label={node[pos=0.75,above,font=\scriptsize]{4}} ]
]
]
]
}
\end{document}

(Note that split here auto siblings option is not used, as we don't really need to remember it. Furthermore, name before <name> is replaced by name before split: again, there is no need to remember the last node of every page forever.)

0

You must log in to answer this question.

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