分页后我的节点不再存在

分页后我的节点不再存在

分页后我的节点(字符串)丢失了。只有在第一页我的节点“100”显示。此代码包含来自@skillmon @ulrike fischer @saso 的部分内容。在此先谢谢您。我知道我应该发布一个更短的代码,但在我看来,我不能再缩短它了,否则它就不再起作用了。提前谢谢您。

\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

非首页上的节点边缘不使用常规 Forest 的边缘绘制机制来绘制。这是因为这些节点的父节点未在此处绘制。树分割代码通过手动绘制这些边缘(split dir tree auto post更准确地说,在\foreach ... \path ...该样式中的行中)解决了该问题。虽然该行指定使用edge节点的选项(.process处理程序将的值放入edge##1,但它并没有告诉 TikZ 绘制edge label(请参阅选项的默认值edge path,手册 3.7.3)。

因此,原则上,在末尾添加##3(设置为edge label)应该可以解决问题。.process\path

    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
        }%
    },

但是, 还有一个额外的问题split dir tree auto post。该样式实际上将第一页上最后一个节点的edge(和edge label) 应用于第二页上的所有边。下面的代码也修复了这个问题。

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

(请注意,split here auto siblings选项未被使用,因为我们实际上不需要记住它。此外,名称before <name>被名称替换before split:同样,没有必要永远记住每个页面的最后一个节点。)

相关内容