나는 PSTricks
매우 매력적이라고 생각하는 사용자 정의 디렉토리 트리를 구현했습니다. 기본적으로 모든 것을 TikZ
. 나는 매우 기본적인 아이디어를 실행하는 데 성공했습니다 TikZ
. 디렉터리와 파일을 만들 수 있습니다. 하지만 이전 항목을 기준으로 위치를 지정하는 방법을 모르겠습니다. 나는 ~에 대해 알고 있다dirtree
패키지이지만 파일과 디렉토리에 대한 기호는 마음에 듭니다.
PSTricks 코드에서는 \par
각각의 새 항목(파일 또는 디렉터리)에 대해 새 단락이 추가됩니다. 나는 TikZ
개별 노드를 서로 상대적으로 배치해야 한다고 생각합니다. 따라서 마지막 노드 이름이나 위치를 저장해야 합니다. 어떻게 할 수 있습니까? 아니면 완전히 다른 방법이 있나요?
PSTricks 코드 작동
J. Stier에 대한 크레딧
암호:
\documentclass{standalone}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[english]{babel}
\usepackage{graphicx}
\usepackage{pstricks, pst-node, pstricks-add}
% ---------------------------
% PST-Directory-Tree
% ---------------------------
% Counter
\newcounter{leaves}
\newcounter{directories}
\newlength{\parskipnew}
\setlength{\parskipnew}{\parskip}
% Environment
\newenvironment{directory}[2][\linewidth]{%
\setcounter{leaves}{0}%
\addtocounter{directories}{1}%
\edef\directoryname{D\thedirectories}%
\begin{minipage}[t]{#1}%
\setlength{\parindent}{\linewidth}%
\addtolength{\parindent}{-\dirshrink\parindent}%
\parskip2pt%
\noindent%
\Rnode[href=-\dirshrink]{\directoryname}{%
\parbox[t]{#1}{%
\parbox[c]{0.65cm}{%
\centering%
\includegraphics[scale=0.7]{Figures/Icons/ordner}%
}%
\hspace{.2em}\texttt{#2}}%
}%
\par
}
{\end{minipage}\vspace{0.5\parskipnew}}
% Commands
\newcommand{\file}[2][]{%
\addtocounter{leaves}{1}%
\edef\leaflabel{L\theleaves\directoryname}%
\par
\Rnode{\leaflabel}{%
\parbox[t]{\dirshrink\linewidth}{%
\parbox[c]{0.65cm}{%
\centering\includegraphics[scale=0.7]{Figures/Icons/datei}%
}%
\hspace{.2em}\texttt{#2}\hfill#1}%
}%
\ncangle[angleA=270,angleB=180,armB=0,nodesepA=3pt,nodesepB=2pt]{\directoryname}{\leaflabel}%
\par%
}
%
\newcommand{\dir}[2][]{%
\addtocounter{leaves}{1}%
\edef\leaflabel{L\theleaves\directoryname}%
\par
\Rnode{\leaflabel}{%
\parbox[t]{\dirshrink\linewidth}{%
\parbox[c]{0.65cm}{%
\centering%
\includegraphics[scale=0.7]{Figures/Icons/ordner}%
}%
\hspace{.2em}\texttt{#2}\hfill#1%
}%
}%
\ncangle[angleA=270,angleB=180,armB=0,nodesepA=3pt,nodesepB=2pt]{\directoryname}{\leaflabel}%
\par%
}
%
\newcommand{\fother}[2][]{%
\addtocounter{leaves}{1}%
\edef\leaflabel{L\theleaves\directoryname}%
\par
\Rnode{\leaflabel}{%
\parbox[t]{\dirshrink\linewidth}{%
\hspace{0.5em}\normalfont{\textit{#2}}\hfill#1
}%
}%
\ncangle[angleA=270,angleB=180,armB=0,nodesepA=3pt,nodesepB=2pt]{\directoryname}{\leaflabel}%
\par%
}
%
\newcommand{\dirfile}[1]{%
\addtocounter{leaves}{1}%
\edef\leaflabel{L\theleaves\directoryname}%
\par
\Rnode{\leaflabel}{%
\parbox[t]{\dirshrink\linewidth}{#1}%
}%
\ncangle[angleA=270,angleB=180,armB=0,nodesepA=3pt,nodesepB=2pt]{\directoryname}{\leaflabel}%
\par%
}
%
\newcommand{\dirshrink}{0.967}
%
\newcommand{\optional}[1]{{\normalfont\mdseries$<$\hspace{0.05em}{\itshape #1}\hspace{0.15em}$>$}}
% ---------------------------
% Document
% ---------------------------
\begin{document}
\begin{pspicture}(6,12.5)
\psset{linewidth=0.5pt}
\rput[lb](0,0.5){
\begin{directory}{\optional{Project}}
\dirfile{%
\begin{directory}{Figures}
\file{fig-1.eps}
\file{fig-1.pdf}
\file{fig-1.png}
\file{fig-2.eps}
\file{fig-2.pdf}
\file{fig-2.png}
\end{directory}%
}
% %
\dirfile{%
\begin{directory}{Scripts}
\file{install\_package\_A.sh}
\file{install\_package\_B.sh}
\file{install\_package\_C.sh}
\end{directory}
}
% %
\dirfile{%
\begin{directory}{Sections}
\file{section-1.tex}
\file{section-2.tex}
\file{section-3.tex}
\file{literature.bib}
\end{directory}
}
% %
\file{project.kilepr}
\file{project.tex}
% %
\end{directory}}
\end{pspicture}
\end{document}
결과:
초기 TikZ 코드
\documentclass{standalone}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[english]{babel}
\usepackage{graphicx}
% \usepackage{pstricks, pst-node, pstricks-add}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\usetikzlibrary{fit}
\usetikzlibrary{positioning}
% ---------------------------
% PST-Directory-Tree
% ---------------------------
% Counter
\newcounter{leaves}
\newcounter{directories}
\newlength{\parskipnew}
\setlength{\parskipnew}{\parskip}
% Environment
\newenvironment{directory}[2][\linewidth]{%
\setcounter{leaves}{0}%
\addtocounter{directories}{1}%
\edef\directoryname{D\thedirectories}%
\begin{minipage}[t]{#1}%
\setlength{\parindent}{\linewidth}%
\addtolength{\parindent}{-\dirshrink\parindent}%
\parskip2pt%
\noindent%
\node (i1\directoryname) {\includegraphics[scale=0.7]{Figures/Icons/ordner}};
\node[right = .2em of i1\directoryname] (i2\directoryname) {\texttt{#2}};
\begin{scope}[on background layer]
\node[fit={(i1\directoryname) (i2\directoryname)}, fill=lightgray, inner sep=0pt] (\directoryname) {};
\end{scope}
}
{\end{minipage}\vspace{0.5\parskipnew}}
% Commands
\newcommand{\file}[2][]{%
\addtocounter{leaves}{1}%
\edef\leaflabel{L\theleaves\directoryname}%
\node[below right= 0.5ex and 0.5em of \directoryname.south](i1\leaflabel) {\includegraphics[scale=0.7]{Figures/Icons/datei}};%
\node[right = .2em of i1\leaflabel] (i2\leaflabel) {\texttt{#2}};
\node[fit={(i1\leaflabel) (i2\leaflabel)}, inner sep=0pt] (\leaflabel) {};
\draw (\directoryname.south) |- (\leaflabel.west);
}
%
\newcommand{\dirshrink}{0.967}
%
\newcommand{\optional}[1]{{\normalfont\mdseries$<$\hspace{0.05em}{\itshape #1}\hspace{0.15em}$>$}}
% ---------------------------
% Document
% ---------------------------
\begin{document}
\begin{tikzpicture}(10,10)
\begin{directory}{\optional{Project}}
\file{fig-1.eps}
\file{fig-2.eps}
\end{directory}
\end{tikzpicture}
\end{document}
필요한 이미지 파일
답변1
방금 아이콘에 대한 이미지를 제공했다는 것을 깨달았습니다. 아, 글쎄요. 다음은 순수한 TikZ 솔루션입니다. 적어도 그것은 사용합니다숲TikZ를 기반으로합니다. 또한 pic
아이콘에 두 개의 를 사용하여 트리 내에서 사용됩니다.
edges
이는 새로운 라이브러리를 다음 용도로 사용합니다 .숲여기에는 folder
디렉토리 트리 스타일이 포함됩니다. 폴더도 그릴 수 있지만 그다지 폴더나 파일이 아니기 때문에 기대에 미치지 못할 수도 있습니다. 여기서 스타일은 나무의 구조적 모양을 자동화하는 데 사용되었습니다.
이것은많이edges
적절한 나무 스타일을 설정해야 했기 때문에 라이브러리를 사용하면 더 쉽습니다 .
원하는 패키지와 라이브러리를 로드합니다.
\documentclass[tikz, border=10pt, multi]{standalone}
\usepackage{forest}
\useforestlibrary{edges}
\begin{document}
라이브러리 의 기본값을 적용합니다 edges
. 다른 종류의 나무를 그릴 계획이라면 이를 TeX 그룹 내에 넣어 범위를 제한하세요.
\forestapplylibrarydefaults{edges}
pic
아이콘에 대해 두 개의 을 만듭니다 .
\tikzset{%
폴더 모양의 경우 mkdir
.
mkdir/.pic={%
\draw [pic actions] (-1.5ex,-1ex) -- ++(0,2ex) -- ++(.25ex,.25ex) -- ++(1.25ex,0) -- ++(.25ex,-.25ex) -- ++(1.25ex,0) |- cycle;
},
파일 모양의 경우 touch
.
touch/.pic={%
\draw [pic actions] (-1ex,-1.5ex) |- ++(1.25ex,3ex) edge ++(.75ex,-.75ex) |- ++(.75ex,-.75ex) |- cycle;
}
}
이제숲optional
대신에 사용할 특정 스타일입니다 \optional{}
.
\forestset{%
optional/.style={%
content/.wrap value={$<$\hspace{0.05em}\normalfont\itshape ##1\hspace{0.15em}$>$},
}
}
이제 환경에서 실제 나무를 살펴보겠습니다 forest
.
\begin{forest}
먼저 일부 사용자 정의.
for tree={
이 설정을 전체 트리에 적용합니다.
font=\ttfamily,
우리는 나무가 오른쪽으로(즉, 비스듬히) 자라기를 원하며 0
, 그렇지 않으면 거꾸로 나오는 자식 순서를 바꿔야 합니다.
grow'=0,
folder
유형 구조를 설정하는 스타일을 적용합니다 pstree
.
folder,
모든 터미널 노드는 파일이고 나머지 노드는 모두 디렉터리입니다. 따라서 각 노드에 자식이 있는지(비터미널) 또는 없는지(터미널) 테스트하여 자동으로 아이콘을 추가할 수 있습니다.
if n children=0{
조정을 조금 지연시켜야 원본 콘텐츠가 설정됩니다. 그런 다음 아이콘을 위한 공간을 만들기 위해 왼쪽에 공간을 추가하겠습니다.
before typesetting nodes={
content/.wrap value={\hspace*{2.5ex}#1},
},
pic
관련 장소에 아이콘을 그리는 TikZ 주석을 추가하겠습니다 . 의 값은 트리가 그려진 후 환경이 종료되기 tikz
전에 있는 그대로 TikZ에 전달될 코드를 지정합니다 . forest
관련 노드의 컨텍스트는 여전히 사용 가능하며 예를 들어 적절하게 배치하기 위해 현재 노드의 앵커에 (.west)
액세스하는 데 사용할 수 있습니다 .west
pic
tikz={%
\pic [xshift=1.5ex] at (.west) {touch};
}
}{
이제 비터미널 노드에 대해서도 동일한 작업을 수행합니다. 여기서는 간격과 pic
차이만 다릅니다.
before typesetting nodes={
content/.wrap value={\hspace*{3.5ex}#1},
},
tikz={%
\pic [xshift=2ex] at (.west) {mkdir};
}
}
},
이제 트리 자체에 대해 스타일을 적용하려는 루트부터 시작합니다 optional
.
[Project, optional
첫 번째 하위 디렉터리
[Figures
그리고 그 내용은 트리에서 말하는 하위 노드입니다.
[fig-1.eps]
[fig-1.pdf]
[fig-1.png]
[fig-2.eps]
[fig-2.pdf]
[fig-2.png]
]
첫 번째 하위 디렉터리를 종료합니다. 트리 루트 노드의 두 번째 자식인 두 번째 하위 디렉터리를 시작합니다.
[Scripts
그리고 그 내용은 이전과 마찬가지로 어린이입니다.
[install\_package\_A.sh]
[install\_package\_B.sh]
[install\_package\_C.sh]
]
하위 디렉터리와 해당 콘텐츠를 계속 추가합니다.
[Sections
[section-1.tex]
[section-2.tex]
[section-3.tex]
[literature.bib]
]
마지막 두 항목은 루트 바로 아래 수준에 있지만 이들 자체는 파일입니다. 즉, 터미널 노드이기도 한 루트의 하위 항목입니다.
[project.kilepr]
[project.tex]
루트를 닫습니다.
]
그리고 트리를 마무리합니다.
\end{forest}
\end{document}
개역 성서
그러나 우리는 더 많은 유연성을 원할 수도 있습니다. 예를 들어 파일과 디렉터리의 아이콘/기호 크기를 더 쉽게 변경하고, 경로와 아이콘 사이의 거리를 제어하고, 아이콘과 이름 사이의 거리를 제어하고 싶을 수도 있습니다. .
우리는 TikZ 설정의 약간 더 강력한 설정과 일부 수정을 통해 이를 수행할 수 있습니다.숲암호. 나에게 있어 가장 까다로운 부분은 내부에서 차원의 배수를 사용하는 방법을 알아내는 것이었습니다 forest
. 예를 들어, 특정 길이 등의 10배만큼 이동하도록 지시하는 방법입니다. 결국 이를 위해 스크래치 차원 레지스터를 사용했지만 이것이 가장 효율적인 솔루션인지는 확실하지 않습니다.
이전과 마찬가지로 일부 TikZ 사용자 정의부터 시작합니다.
\tikzset{%
우리는 일부 매크로가 다양한 차원을 유지하여 쉽게 수정할 수 있기를 원합니다. 이를 위해 4개의 매크로를 사용하겠습니다.
\mkdirsize
디렉터리 아이콘의 기본 크기(너비 = 12 x 기본 크기)touchsize
파일 아이콘의 기본 크기(너비 = 8 x 기본 크기)\iconsep
아이콘과 이름 사이의 거리;\iconsepfrompath
경로와 아이콘 사이의 거리.
이는 TikZ 스타일로 수정 가능합니다.
mkdir size
;touch size
;icon sep
;icon sep from path
.
구성은 다음과 같습니다.
mkdir size/.store in=\mkdirsize,
touch size/.store in=\touchsize,
icon sep/.store in=\iconsep,
icon sep from path/.store in=\iconsepfrompath,
우리는 모든 것이 기본값을 가지고 있는지 확인합니다.
mkdir size=.25ex,
touch size=.25ex,
icon sep=1.5ex,
icon sep from path=1ex,
이제 우리는 s가 및 pic
값을 기반으로 하길 원합니다 .mkdir size
touch size
또한 트리 내에서 아이콘의 위치를 올바르게 조정하기가 더 쉽기 때문에 왼쪽으로 이동하는 대신 각 pic
항목 의 가장 왼쪽 지점을 배치했습니다 .x=0
mkdir/.pic={%
\draw [pic actions] (0,-4*\mkdirsize) -- ++(0,8*\mkdirsize) -- ++(\mkdirsize,\mkdirsize) -- ++(5*\mkdirsize,0) -- ++(\mkdirsize,-\mkdirsize) -- ++(5*\mkdirsize,0) |- cycle;
},
touch/.pic={%
\draw [pic actions] (0,-6*\touchsize) |- ++(5*\touchsize,12*\touchsize) edge ++(3*\touchsize,-3*\touchsize) |- ++(3*\touchsize,-3*\touchsize) |- cycle;
},
}
icon sep
또한 및 의 값을 사용하도록 트리의 프리앰블을 조정하고 싶습니다 icon sep from path
.
\begin{forest}
그러나 우리는 이전처럼 시작합니다.
for tree={
font=\ttfamily,
grow'=0,
folder,
노드가 있어야 하는 위치와 기본 노드 콘텐츠 앞에 삽입되어야 하는 공간을 지정하는 데 변경 사항이 적용됩니다. 이 부분이 제가 고민했던 부분입니다. 이는 효과가 있지만 가장 효과적이고 효율적인 솔루션은 아닐 수 있습니다.
if n children=0{
before typesetting nodes={
스크래치 레지스터 차원을 사용하여 노드 콘텐츠에 추가할 공간의 양을 계산합니다.
tempdima=\iconsepfrompath+\iconsep+8*\touchsize,
content/.wrap value={\expandafter\hskip \foresteregister{tempdima}#1},
},
pic
그런 다음 을 적절한 양만큼 오른쪽으로 이동해야 합니다 .
tikz={%
\pic [xshift=\iconsepfrompath] at (.west) {touch};
},
}{
디렉토리 노드의 경우에는 복잡합니다. 왜냐하면 이들 중 하나가 루트에 있고 pic
바로 여기로 이동되어서는 안 되며 노드의 내용에 더 적은 공간이 추가되어야 하기 때문입니다. 그래서 우리는 이 사건을 별도로 다룬다.
if level=0{
디렉토리 기호를 이동하지 마십시오.
tikz={%
\pic at (.west) {mkdir};
},
노드에 공간을 추가하지만 icon sep from path
루트 디렉터리와는 관련이 없으므로 값을 추가하지 마세요.
before typesetting nodes={
tempdima=\iconsep+12*\mkdirsize,
content/.wrap value={\expandafter\hskip \foresteregister{tempdima}#1},
},
이제 루트가 아닌 디렉토리에 대해 설명합니다.
}{
tikz={%
\pic [xshift=\iconsepfrompath] at (.west) {mkdir};
},
before typesetting nodes={
tempdima=\iconsepfrompath+\iconsep+12*\mkdirsize,
content/.wrap value={\expandafter\hskip \foresteregister{tempdima}#1},
},
},
},
},
전체 코드:
\documentclass[tikz, border=10pt, multi]{standalone}
\usepackage{forest}
\useforestlibrary{edges}
\begin{document}
\forestapplylibrarydefaults{edges}
\tikzset{%
mkdir/.pic={%
\draw [pic actions] (0,-4*\mkdirsize) -- ++(0,8*\mkdirsize) -- ++(\mkdirsize,\mkdirsize) -- ++(5*\mkdirsize,0) -- ++(\mkdirsize,-\mkdirsize) -- ++(5*\mkdirsize,0) |- cycle;
},
touch/.pic={%
\draw [pic actions] (0,-6*\touchsize) |- ++(5*\touchsize,12*\touchsize) edge ++(3*\touchsize,-3*\touchsize) |- ++(3*\touchsize,-3*\touchsize) |- cycle;
},
mkdir size/.store in=\mkdirsize,
touch size/.store in=\touchsize,
icon sep/.store in=\iconsep,
icon sep from path/.store in=\iconsepfrompath,
mkdir size=.25ex,
touch size=.25ex,
icon sep=1.5ex,
icon sep from path=1ex,
}
\forestset{%
optional/.style={%
content/.wrap value={$<$\hspace{0.05em}\normalfont\itshape ##1\hspace{0.15em}$>$},
},
}
\begin{forest}
for tree={
font=\ttfamily,
grow'=0,
folder,
if n children=0{
before typesetting nodes={
tempdima=\iconsepfrompath+\iconsep+8*\touchsize,
content/.wrap value={\expandafter\hskip \foresteregister{tempdima}#1},
},
tikz={%
\pic [xshift=\iconsepfrompath] at (.west) {touch};
},
}{
if level=0{
tikz={%
\pic at (.west) {mkdir};
},
before typesetting nodes={
tempdima=\iconsep+12*\mkdirsize,
content/.wrap value={\expandafter\hskip \foresteregister{tempdima}#1},
},
}{
tikz={%
\pic [xshift=\iconsepfrompath] at (.west) {mkdir};
},
before typesetting nodes={
tempdima=\iconsepfrompath+\iconsep+12*\mkdirsize,
content/.wrap value={\expandafter\hskip \foresteregister{tempdima}#1},
},
},
},
},
[Project, optional
[Figures
[fig-1.eps]
[fig-1.pdf]
[fig-1.png]
[fig-2.eps]
[fig-2.pdf]
[fig-2.png]
]
[Scripts
[install\_package\_A.sh]
[install\_package\_B.sh]
[install\_package\_C.sh]
]
[Sections
[section-1.tex]
[section-2.tex]
[section-3.tex]
[literature.bib]
]
[project.kilepr]
[project.tex]
]
\end{forest}
\end{document}
답변2
이것은 실제로 귀하의 질문에 대한 답변은 아니지만 쉽게 유지 관리하고 조작할 수 있는 유용한 레이아웃이라고 생각합니다. 또한 일부 비표준 구조도 허용됩니다. 아직 파일 아이콘을 포함하는 방법을 알아내지 못했습니다. 또한 탭 컨트롤 열을 합리적으로 잘 정렬된 상태로 유지하는 경우에도 가장 잘 작동합니다.
\documentclass{standalone}
\usepackage{menukeys}
\newmenumacro{\nixfile}[/]{hyphenatepaths}
\newmenumacro{\nixpath}[/]{hyphenatepathswithfolder}
\newmenumacro{\winpath}[bslash]{hyphenatepathswithfolder}
\newmenumacro{\winfile}[bslash]{hyphenatepaths}
\begin{document}
\begin{minipage}{\textwidth}
\begin{tabbing}
\hspace{1em}\=\hspace{1em}\=\hspace{1em}\=\hspace{12em}\=\\\kill
\nixpath{root/path } \>\>\>\> Main Root \+\\
\nixpath{subfolder } \>\>\> Specialized subfolder \+\\
\nixfile{subfile } \>\> Some file \-\\
\nixfile{wierd/file} \>\>\> Important subfile, unimportant subfolders \\
\nixfile{file } \>\>\> Main file \\
\end{tabbing}
\end{minipage}
\end{document}