Hallo,

Was kann mein Code? Mein Code erzeugt einen Pagebreak in einer Tikz Umgebung. Diesen Programm Code habe ich von Sašo Živanović: http://tex.stackexchange.com/a/296771/ übernommen. Danke an dieser Stelle. So weit so gut.

Was für welche Einschränkungen hat dieser Code: Leider funktioniert mein Code (Page Break + File Tree) nur dann wenn der File Tree länger als 1 Seite ist. Dh: Erst dann wenn ein Pagebreak möglich ist. Ist der File Tree kürzer als 1 Seite bekomme ich eine Fehlermeldung -> Paragraph ended before \forestOeappto was complete. \end{forest} usw. Damit es trotzdem funktioniert muss ich folgende Zeile auskommentieren -> split dir tree auto,

Wir verwenden Latex als Bericht Automatisierung. Wir wissen nie wie lange der File Tree ist. Somit suchen wir einen Code der beide Fälle gleichzeitig abdeckt ohne manuell eingreifen zu müssen und den Code umzuschreiben wenn der Filetree zu kurz ist. Ich hoffe es gibt dafür eine Lösung. Ich bin zwar Programmierer (c#) aber mit Latex tue ich mir sehr schwer Fuß zu fassen. Sorry für die Unannehmlichkeiten und nochmals Danke.

Der Code ist wirklich so lange .... ich kann ihn nicht kürzen. Der Code besteht aus 2 Teile. 1 Teil ist für den Pagebreak verantwortlich der 2 Teil für den File Tree. In meinem Beispiel habe ich den File Tree sehr kurz gehalten um die Fehlermeldung zu provozieren (wenn split file tree) einkommentiert ist. Wird der File Tree erweitert bekomme ich wenn ich split dir tree auto einkommentiere keine Fehlermeldung. UPDATE1 Kann ich split dir tree auto, diese Programzeile mit einer If Abfrage ein oder ausschalten bzw. ausführen oder nicht ausführen?

Öffne in Overleaf
\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

\begin{document}    
\begin{forest}
    for tree={
        folder,
        grow'=0,
        fit=band,
    },
    %split dir tree auto, ->Auskommetiert damit es funktioniert
    [ XYZ
    [ XYZ
    [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}}
     [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}}
    ]
    ]
    ]
    ]
\end{forest}

\end{document}

gefragt 28 Sep, 04:28

helmutW's gravatar image

helmutW
1063
Akzeptiert: 62%

bearbeitet 28 Sep, 07:25


Das Folgende definiert einen Befehl \AutoSplittedTree, der zunächst den forest erstellt, ohne die Option split dir tree auto zu verwenden, anschließend prüft, ob das Resultat kleiner oder größer als der restliche verfügbare Platz auf der Seite ist, und schließlich den Tree entsprechend des Resultats der Probe ausgibt.

Der Test könnte zu einem falschen Ergebnis führen, weshalb das Macro auch eine gesternte Form besitzt, welche keinen Test durchführt, sondern direkt die Option split dir tree auto mit verwendet. Ferner besitzt das Macro ein optionales Argument, welches als Standardwert for tree = { folder, grow'=0, fit=band, } verwendet.

Code:

Öffne in Overleaf
\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,font=\scriptsize]{1}}
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
        ]
      ]
    ]
  }
\AutoSplittedTree
  {
    [ XYZ
      [ XYZ
        [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}}
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
         [ XYZ,edge label={node[pos=0.75,above,font=\scriptsize]{1}} ]
        ]
      ]
    ]
  }
\end{document}

Resultat:

Erste Seite

Zweite Seite

Permanenter link

beantwortet 28 Sep, 14:34

Skillmon's gravatar image

Skillmon
3714

@skillmon Danke für diese Lösung. Bzw. Danke all die anderen! Für mich ist es unbegreiflich wie sehr ihr mit Latex vertraut seid und wie schnell ihr spezifische Lösungen hervorbringt... Ich bin fast ein wenig neidisch....

(03 Okt, 03:35) helmutW

@helmutW versuche einfach über ein Jahr, sämtliche Fragen auf TeX.SX zu beantworten, und bei jenen, bei denen du keine Antwort erstellen kannst, schaust du dir die Lösungen der anderen an und versuchst, sie zu verstehen. Danach bekommst du das eventuell auch hin :) Und anschließend liest du noch das TeXbook und TeX by Topic durch (das fehlt mir noch)...

(03 Okt, 04:11) Skillmon

@Skillmon ich glaube dafür bräuchte ich mehr Zeit als ein paar Stunden im Monat. Ich bin leider nur ein Anwender bzw. Anfänger. Meiner Meinung nach fehlt es an einer übergreifenden Doku. Einzelne Dinge wie Textformatierung sind sehr gut beschrieben aber wenn uns um "tiefe" Programmierung geht fehlt mir einfach eine Doku. Leider habe ich noch eine letzte Frage. Wie kann ich die Horizontale Linie strecken? Wenn mein Node mehrere Zeichen hat? Mit before computing xy={l=100pt}?? Soll ich diese weitere kleine Frage in meinem Post aktualisieren? Oder eine neue Frage stellen? Danke.

(03 Okt, 04:41) helmutW
1

@helmutW besser du stellst eine neue Frage. Ich bin nicht außergewöhnlich gut mit TikZ und Konsorten und habe jetzt gerade keine Zeit.

(03 Okt, 07:10) Skillmon
Deine Antwort auf die Frage (nicht auf andere Antworten)
Knebel-Vorschau

Folge dieser Frage

Per E-Mail:

Wenn Du Dich anmeldest, kannst Du Updates hier abonnieren

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs füge einfach zwei Leerzeichen an die Stelle ein, an der die neue Zeile sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Zugeordnete Themen:

×627
×2
×2

Frage gestellt: 28 Sep, 04:28

Frage wurde angeschaut: 325 Mal

Zuletzt aktualisiert: 03 Okt, 07:10