Eu tenho uma PSTricks
implementação de uma árvore de diretórios personalizada que considero bastante atraente. Basicamente, quero converter tudo para TikZ
. Consegui colocar a ideia básica em execução TikZ
: posso criar um diretório e um arquivo. Mas não tenho ideia de como posicioná-los em relação ao item anterior. eu sei dodirtree
pacote, mas gosto dos símbolos para arquivos e diretórios.
No código PSTricks um novo parágrafo é adicionado \par
para cada novo item (arquivo ou diretório). Eu TikZ
tenho que posicionar os nós individuais em relação uns aos outros, eu acho. Portanto, tenho que salvar o nome ou local do último nó. Como isso pode ser feito? Ou existe uma outra maneira completamente diferente?
Código PSTricks funcionando
Créditos a J. Stier
Código:
\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}
Resultado:
Código TikZ inicial
\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}
Arquivos de imagem necessários
Responder1
Acabei de perceber que você forneceu imagens para os ícones. Ah bem. Aqui está uma solução TikZ pura. Pelo menos, ele usaflorestaque é baseado em TikZ. Além disso, utiliza dois pic
s para os ícones, que são então utilizados dentro da árvore.
Isso faz uso da nova edges
biblioteca paraflorestaque inclui um folder
estilo para árvores de diretórios. Ele também pode desenhar as pastas, mas elas não são muito parecidas com pastas ou arquivos, então provavelmente não atenderiam às suas expectativas. Aqui, o estilo é usado apenas para automatizar a aparência estrutural da árvore.
Isso émuitomais fácil com a edges
biblioteca, pois isso exigia a configuração de um estilo de árvore adequado.
Carregue os pacotes e a biblioteca que desejamos.
\documentclass[tikz, border=10pt, multi]{standalone}
\usepackage{forest}
\useforestlibrary{edges}
\begin{document}
Aplique os padrões da edges
biblioteca. Se você planeja desenhar outros tipos de árvores, coloque isso dentro de um grupo TeX para limitar o escopo.
\forestapplylibrarydefaults{edges}
Criamos dois pic
s para os ícones.
\tikzset{%
Para formatos de pasta, mkdir
.
mkdir/.pic={%
\draw [pic actions] (-1.5ex,-1ex) -- ++(0,2ex) -- ++(.25ex,.25ex) -- ++(1.25ex,0) -- ++(.25ex,-.25ex) -- ++(1.25ex,0) |- cycle;
},
Para formatos de arquivo, touch
.
touch/.pic={%
\draw [pic actions] (-1ex,-1.5ex) |- ++(1.25ex,3ex) edge ++(.75ex,-.75ex) |- ++(.75ex,-.75ex) |- cycle;
}
}
Agora umfloresta-estilo específico, optional
que usaremos no lugar de \optional{}
.
\forestset{%
optional/.style={%
content/.wrap value={$<$\hspace{0.05em}\normalfont\itshape ##1\hspace{0.15em}$>$},
}
}
Agora, para a árvore real, no forest
ambiente.
\begin{forest}
Primeiro alguma personalização.
for tree={
Aplique essas configurações a toda a árvore.
font=\ttfamily,
Queremos que a árvore cresça para a direita, ou seja, em um ângulo de 0
e precisamos inverter a ordem dos filhos, caso contrário ela sairá de cabeça para baixo.
grow'=0,
Aplique o folder
estilo, que configura a pstree
estrutura do tipo.
folder,
Todos os nós terminais são arquivos, enquanto todos os outros são diretórios. Assim, podemos adicionar os ícones automaticamente testando se cada nó possui algum filho (não terminal) ou não (terminal).
if n children=0{
Precisamos atrasar um pouco o ajuste, para que o conteúdo original esteja definido. Em seguida, adicionaremos algum espaço à esquerda para dar espaço ao ícone.
before typesetting nodes={
content/.wrap value={\hspace*{2.5ex}#1},
},
Adicionaremos uma anotação TikZ que desenhará o pic
ícone no local relevante. tikz
O valor de especifica o código que será passado para o TikZ como está depois que a árvore for desenhada, mas antes do forest
ambiente ser finalizado. O contexto do nó relevante ainda está disponível e podemos usar, por exemplo, (.west)
para acessar a west
âncora do nó atual para posicioná-la pic
adequadamente.
tikz={%
\pic [xshift=1.5ex] at (.west) {touch};
}
}{
Agora fazemos o mesmo para os nós não terminais. Apenas o espaçamento e a pic
variação aqui.
before typesetting nodes={
content/.wrap value={\hspace*{3.5ex}#1},
},
tikz={%
\pic [xshift=2ex] at (.west) {mkdir};
}
}
},
Agora, para a árvore em si, começando com a raiz à qual queremos aplicar o optional
estilo.
[Project, optional
Primeiro subdiretório
[Figures
e seu conteúdo, que são nós filhos em linguagem de árvore.
[fig-1.eps]
[fig-1.pdf]
[fig-1.png]
[fig-2.eps]
[fig-2.pdf]
[fig-2.png]
]
Finalize o primeiro subdiretório. Inicie o segundo subdiretório, que é o segundo filho do nó raiz da árvore.
[Scripts
E seu conteúdo são crianças, como antes.
[install\_package\_A.sh]
[install\_package\_B.sh]
[install\_package\_C.sh]
]
Continue adicionando subdiretórios e seus conteúdos.
[Sections
[section-1.tex]
[section-2.tex]
[section-3.tex]
[literature.bib]
]
As duas últimas entradas estão no nível logo abaixo da raiz, mas são arquivos, ou seja, filhos da raiz, que também são nós terminais.
[project.kilepr]
[project.tex]
Feche a raiz.
]
E termine a árvore.
\end{forest}
\end{document}
VERSÃO REVISADA
Poderíamos, no entanto, querer mais flexibilidade. Por exemplo, podemos querer alterar mais facilmente o tamanho dos ícones/símbolos dos arquivos e diretórios, e controlar as distâncias entre o caminho e o ícone, por um lado, e o ícone e o nome, por outro. .
Podemos fazer isso com um conjunto um pouco mais poderoso de configurações do TikZ e algumas modificações noflorestacódigo. A parte mais complicada disso, para mim, foi descobrir como usar múltiplos de dimensões dentro de arquivos forest
. Por exemplo, como dizer para mudar algo 10 vezes em um determinado comprimento ou algo assim. Eventualmente, usei um registro de dimensão zero para isso, mas não tenho certeza se essa é a solução mais eficiente.
Começamos, como antes, com algumas customizações do TikZ.
\tikzset{%
Queremos que algumas macros mantenham várias dimensões para que possam ser facilmente modificadas. Usaremos 4 macros para isso.
\mkdirsize
para o tamanho base do ícone do diretório (largura = 12 x tamanho base);touchsize
para o tamanho base do ícone do arquivo (largura = 8 x tamanho base);\iconsep
pela distância entre o ícone e o nome;\iconsepfrompath
para a distância entre o caminho e o ícone.
Eles serão modificáveis como estilos TikZ.
mkdir size
;touch size
;icon sep
;icon sep from path
.
Aqui está a configuração:
mkdir size/.store in=\mkdirsize,
touch size/.store in=\touchsize,
icon sep/.store in=\iconsep,
icon sep from path/.store in=\iconsepfrompath,
Garantimos que tudo tenha um valor padrão.
mkdir size=.25ex,
touch size=.25ex,
icon sep=1.5ex,
icon sep from path=1ex,
Agora queremos que nossos pic
s sejam baseados nos valores de mkdir size
e touch size
.
Também colocamos o ponto mais à esquerda de cada um pic
em x=0
vez de deslocá-lo para a esquerda, porque isso facilita o ajuste correto da localização dos ícones na árvore.
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;
},
}
Também queremos adaptar o preâmbulo da árvore para usar os valores de icon sep
e icon sep from path
.
\begin{forest}
Começamos como antes, no entanto.
for tree={
font=\ttfamily,
grow'=0,
folder,
As mudanças vêm na especificação de onde os nós devem estar e o espaço que deve ser inserido antes do conteúdo do nó principal. Esta parte é a parte com a qual tive problemas. Isso funciona, mas pode não ser a solução mais eficaz ou eficiente.
if n children=0{
before typesetting nodes={
Usamos uma dimensão de registro temporário para calcular quanto espaço adicionar ao conteúdo do nó.
tempdima=\iconsepfrompath+\iconsep+8*\touchsize,
content/.wrap value={\expandafter\hskip \foresteregister{tempdima}#1},
},
Precisamos então também deslocá-lo pic
para a direita na quantidade apropriada.
tikz={%
\pic [xshift=\iconsepfrompath] at (.west) {touch};
},
}{
Há uma complicação no caso dos nós do diretório, pois um deles está na raiz e pic
não deve ser deslocado aqui mesmo, e menos espaço deve ser adicionado ao conteúdo do nó. Portanto, tratamos deste caso separadamente.
if level=0{
Não mude o símbolo do diretório.
tikz={%
\pic at (.west) {mkdir};
},
Adicione o espaço ao nó, mas não adicione o valor de, icon sep from path
pois isso é irrelevante para o diretório raiz.
before typesetting nodes={
tempdima=\iconsep+12*\mkdirsize,
content/.wrap value={\expandafter\hskip \foresteregister{tempdima}#1},
},
Agora, para os diretórios não raiz.
}{
tikz={%
\pic [xshift=\iconsepfrompath] at (.west) {mkdir};
},
before typesetting nodes={
tempdima=\iconsepfrompath+\iconsep+12*\mkdirsize,
content/.wrap value={\expandafter\hskip \foresteregister{tempdima}#1},
},
},
},
},
Código completo:
\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}
Responder2
Isso realmente não responde à sua pergunta, mas acho que é um layout útil que pode ser facilmente mantido e manipulado. Também permite alguma estrutura não padronizada. Ainda não descobri como incluir ícones de arquivos. Também funciona melhor se você mantiver as colunas de controle das guias razoavelmente bem alinhadas.
\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}