我正在尝试实现这种方法用于在 IEEETran 格式(双列)中跨多页生成树。我不想在每页的每一列上继续森林的一部分(森林的每一部分跨页面的 2 列)。周围的内部\begin{forest}
会\begin{figure*}
破坏页面中间的森林,并且不会跨多页。
梅威瑟:
\documentclass[journal]{IEEEtran}
\usepackage{geometry,blindtext,romannum}
\usepackage[edges]{forest}
\def\hiddenparcommand{\par}
\newcommand\otherhiddenparcommand{\par\noindent}
\newcommand\hiddencommacommand{, }
\forestset{%
declare keylist register={split here ids},
split here ids={},
declare keylist register={split here interjects}, the tree parts
split here interjects={},
declare keylist={split here auto siblings}{},
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={
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
}%
}{},
split here auto siblings/.register=tempkeylistc,
tikz+/.process={
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,
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,
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
}{},
},
},
},
}
\begin{document}
\begin{forest}
for tree={
folder,
grow'=0,
fit=band,
},
split dir tree auto,
[ Topics
[ \Romannum{1}.\, Introduction]
[ \Romannum{2}.\, Techniques
[ \Romannum{2}-A.\, Principles of Simulation]
[ \Romannum{2}-B.\, Classification of Techniques
[\Romannum{2}-B.1\, Implicit Techniques]
[\Romannum{2}-B.2\, Partitioning]
[\Romannum{2}-B.3\, Simulation]
[\Romannum{2}-B.4\, Algorithms]
]
[\Romannum{2}-C.\, Overview
[\Romannum{2}-C.1\, Advantages of Simulation
[\Romannum{2}-C.1.a\, Computational Burden]
[\Romannum{2}-C.1.b\, Accuracy]
[\Romannum{2}-C.1.c\, System Dynamics]
[\Romannum{2}-C.1.d\, Stability]
]
[\Romannum{2}-C.2\, Challenges
[\Romannum{2}-C.2.a\, Synchronization]
[\Romannum{2}-C.2.b\, Subsystems]
]
]
]
[ \Romannum{3}.\, Methods
[\Romannum{3}-A.\, Classification
[\Romannum{3}-A.1\, Model-one]
[\Romannum{3}-A.2\, Model-two]
]
[\Romannum{3}-B.\, Comparison
[\Romannum{3}-B.1\, Time]
[\Romannum{3}-B.2\, Frequency]
[\Romannum{3}-B.3\, Mixed]
]
[\Romannum{3}-C.\, Evaluation
[\Romannum{3}-C.1\, Efficiency]
[\Romannum{3}-C.2\, Accuracy]
[\Romannum{3}-C.3\, Ease of Use]
]
]
]
\end{forest}
\end{document}
答案1
編輯 3ish
好的。这在最低限度的测试中是可行的。树的不同部分设置在 中figure*
。这意味着它们不一定位于连续的页面上。这是否应该被视为错误或功能是一个悬而未决的问题,但这就是它的工作原理。我不知道此类对“连续”浮动有什么规定。据推测,这些树将以通常的方式运行。
此版本还伪造了缺失的线条,并将树分成三部分或更多部分。当子节点与父节点相距多个分支时,它也有效。
这段代码可能不是最有效的方法。我的目的只是得到一些能起作用的东西。与以前的版本相比,这段代码以不显然立即有缺陷。毫无疑问代码是有 bug,但目前我不知道 bug 是什么。因此它不会受到完全相同的警告。
即使是这样,
买者自负
\documentclass[journal]{IEEEtran}
% \documentclass[a4paper,twocolumn]{article}
\usepackage{geometry,kantlipsum,romannum}
\usepackage[edges]{forest}
% ateb: https://tex.stackexchange.com/a/703055 addaswyd o ateb: ateb: https://tex.stackexchange.com/a/339790/
% a gafodd ei addasu o gôd Sašo Živanović: https://tex.stackexchange.com/a/296771/
\def\hiddenparcommand{\par}
\newcommand\otherhiddenparcommand{\par\noindent}
\newcommand\hiddencommacommand{, }
\newdimen\tempcoordpx
\newdimen\tempcoordtx
\newdimen\tempcoordpy
\newdimen\tempcoordty
\makeatletter
\forestset{%
declare keylist register={split here ids},
split here ids={},
declare keylist register={split here interjects},
split here interjects={},
declare keylist={split here auto siblings}{},
declare keylist={split here auto ancestors}{},
declare toks register=split here toks,
split here toks={},
declare count={split dir tree split}{0},
declare count register={split dir tree splits},
split dir tree splits'=0,
declare dimen register=tmpdima,
tmpdima'=0pt,
declare dimen register=tmpdimb,
tmpdimb'=0pt,
declare dimen register=tmpdimc,
tmpdimc'=0pt,
declare dimen register=tmpdimd,
tmpdimd'=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:{#1}{}},
},
split dir tree pre/.default={[cont.]},
split dir tree post/.style={%
label={[font=\scriptsize, anchor=south, text=gray]above:{#1}{}},
},
split dir tree post/.default={[cont.]},
split dir tree auto pre/.style={%
tempkeylistd'={},
tmpdimd/.option=y,
split option={split here auto ancestors}{,}{split dir tree auto pre aux},
split here auto ancestors'/.register=tempkeylistd,
tikz+/.process={%
OOw2{edge}{split dir tree split}
{
\path (current top ##2);
\pgfgetlastxy{\tempcoordtx}{\tempcoordty}
\edef\tempa{\foresteoption{split here auto ancestors}}
\foreach \i in \tempa {
\pgf@relevantforpicturesizefalse
\path (\i.parent anchor);
\pgf@relevantforpicturesizetrue
\pgfgetlastxy{\tempcoordpx}{\tempcoordpy}
\ifdim\tempcoordty>\tempcoordpy\let\tempcoordty\tempcoordpy\fi
\def\tempb{[cont.]}
\path [##1] (\tempcoordpx,\tempcoordty) ++(\forestregister{folder indent},0pt) coordinate (a) -- ([yshift=-1ex]a |- .parent anchor) ;
}
}
},
},
split dir tree auto pre aux/.style={%
for Nodewalk={on invalid=fake}{name=#1,last}{%
if={>OR<{y}{tmpdimd}}{tempkeylistd+=#1}{}%
},
},
split dir tree auto post/.style={
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
}%
}{},
split here auto siblings/.register=tempkeylistc,
tikz+/.process={
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,
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,
for nodewalk={
draw tree processing order/.style={
filter={tree}{> ORw+n< OR> & {id}{tempcounta}{########1+1}{id}{tempcountb}}%
}
}{},
begin draw/.code={\begin{figure*}\centering\begin{tikzpicture}},
end draw/.code={\end{tikzpicture}\end{figure*}},
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}}
}
}{},
begin draw/.code={\begin{figure*}\centering\begin{tikzpicture}},
end draw/.code={\end{tikzpicture}\end{figure*}},
for root'={draw tree},
},
for tree={%
folder,
grow'=0,
fit=band,
},
}%
},
split dir here auto/.style n args=2{
split dir tree pre,
tempkeylista={},
tempcounta'=0,
tempcountb/.option=split dir tree split,
for current and ancestors={%
if={>OR>{n children}{tempcounta}}{%
for children={%
if={>OR>{n}{tempcounta}}{%
tikz+/.process={
OORw+nw3{edge}{!u.name}{tempcountb}{##1+1}
{
\coordinate (a) at ({forest cs:##2.parent anchor} |- current top ##3.north);
\path [##1] ({forest cs:##2.parent anchor} |- current top ##3.north) ++(\forestregister{folder indent},1ex) |- (.child anchor);
}
},
}{},
},
tempkeylista+/.option=name,
}{},
tempcounta/.option=n,
},
split here auto ancestors/.register=tempkeylista,
split dir tree auto pre,
!next node.split dir tree auto post=#2,
split 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,
alias=current top 0,
before drawing tree={
tempdima/.max={y}{tree},
tempdimc/.register=tempdima,
tempdimd/.min={y}{tree},
tempdima-/.register=tempdimd,
tmpdima'=10ex,
tmpdimc'=\pagetotal,
while={
>Rd>{tempdima}{\textheight}
}{
for nodewalk={
root',
split dir tree split/.register=split dir tree splits,
until={
> ROw2+d RRw2+d > {tempdimc}{y}{##1-##2} {tmpdima}{tmpdimc}{\textheight-##2-##1}
}{next node,split dir tree split/.register=split dir tree splits},
if nodewalk valid={previous node}{%
previous node,
split dir here auto/.process={R_w2{tmpdima}{}{{##2}{##1}}},
split dir tree splits'+=1,
next node,
split dir tree split/.register=split dir tree splits,
alias=current top \forestoption{split dir tree split},
}{},
tempdima/.option=y,
tempdimc/.register=tempdima,
tempdima-/.register=tempdimd,
tmpdima'=15ex,
tmpdimc'=0pt
}{},
},
},
},
}
\makeatother
\begin{document}
\begin{forest}
split dir tree auto,
[ Topics
[ \Romannum{1}.\, Introduction]
[ \Romannum{2}.\, Techniques
[ \Romannum{2}-A.\, Principles of Simulation]
[ \Romannum{2}-B.\, Classification of Techniques
[\Romannum{2}-B.1\, Implicit Techniques]
[\Romannum{2}-B.2\, Partitioning]
[\Romannum{2}-B.3\, Simulation]
[\Romannum{2}-B.4\, Algorithms]
]
[\Romannum{2}-C.\, Overview
[\Romannum{2}-C.1\, Advantages of Simulation
[\Romannum{2}-C.1.a\, Computational Burden]
[\Romannum{2}-C.1.b\, Accuracy]
[\Romannum{2}-C.1.c\, System Dynamics]
[\Romannum{2}-C.1.d\, Stability]
]
[\Romannum{2}-C.2\, Challenges
[\Romannum{2}-C.2.a\, Synchronization]
[\Romannum{2}-C.2.b\, Subsystems]
]
]
]
[ \Romannum{3}.\, Methods
[\Romannum{3}-A.\, Classification
[\Romannum{3}-A.1\, Model-one]
[\Romannum{3}-A.2\, Model-two]
]
[\Romannum{3}-B.\, Comparison
[\Romannum{3}-B.1\, Time]
[\Romannum{3}-B.2\, Frequency]
[\Romannum{3}-B.3\, Mixed]
]
[\Romannum{3}-C.\, Evaluation
[\Romannum{3}-C.1\, Efficiency]
[\Romannum{3}-C.2\, Accuracy]
[\Romannum{3}-C.3\, Ease of Use]
]
]
]
\end{forest}
\kant[1-5]
\begin{forest}
split dir tree auto,
[ Topics
[ \Romannum{1}.\, Introduction]
[ \Romannum{2}.\, Techniques
[ \Romannum{2}-A.\, Principles of Simulation]
[ \Romannum{2}-B.\, Classification of Techniques
[\Romannum{2}-B.1\, Implicit Techniques]
[\Romannum{2}-B.2\, Partitioning]
[\Romannum{2}-B.3\, Simulation]
[\Romannum{2}-B.4\, Algorithms]
]
[\Romannum{2}-C.\, Overview
[\Romannum{2}-C.1\, Advantages of Simulation
[\Romannum{2}-C.1.a\, Computational Burden]
[\Romannum{2}-C.1.b\, Accuracy]
[\Romannum{2}-C.1.c\, System Dynamics]
[\Romannum{2}-C.1.d\, Stability]
]
[\Romannum{2}-C.2\, Challenges
[\Romannum{2}-C.2.a\, Synchronization]
[\Romannum{2}-C.2.b\, Subsystems]
]
]
]
[ \Romannum{3}.\, Methods
[\Romannum{3}-A.\, Classification
[\Romannum{3}-A.1\, Model-one]
[\Romannum{3}-A.2\, Model-two]
]
[\Romannum{3}-B.\, Comparison
[\Romannum{3}-B.1\, Time]
[\Romannum{3}-B.2\, Frequency]
[\Romannum{3}-B.3\, Mixed]
]
[\Romannum{3}-C.\, Evaluation
[\Romannum{3}-C.1\, Efficiency]
[\Romannum{3}-C.2\, Accuracy]
[\Romannum{3}-C.3\, Ease of Use]
]
]
]
\end{forest}
\kant[6-10]
\begin{forest}
split dir tree auto,
[a[b[c[d[e[f[g[h[i[j[k[l[m[n[o[p[q[r[s[t[u[v[w[x[y[z]]]]]]]]]]]]]]]]]]]]]]]]][b[c[ch[d[dd[e[f[ff[g[ng[h[i[l[ll[m[n[o[p[ph[r[rh[s[t[th[u[w[y]]]]]]]]]]]]]]]]]]]]]]]]]][c[d[e[f[g[h[i[j[k[l[m[n[o[p[q[r[s[t[u[v[w[x[y[z]]]]]]]]]]]]]]]]]]]]]]]]]]
\end{forest}
\end{document}