VERSÃO REVISADA

VERSÃO REVISADA

Eu tenho uma PSTricksimplementaçã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 dodirtreepacote, mas gosto dos símbolos para arquivos e diretórios.

No código PSTricks um novo parágrafo é adicionado \parpara cada novo item (arquivo ou diretório). Eu TikZtenho 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:

Resultado PSTricks

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

datai.png pedido.png

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 pics para os ícones, que são então utilizados dentro da árvore.

Isso faz uso da nova edgesbiblioteca paraflorestaque inclui um folderestilo 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 edgesbiblioteca, 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 edgesbiblioteca. Se você planeja desenhar outros tipos de árvores, coloque isso dentro de um grupo TeX para limitar o escopo.

\forestapplylibrarydefaults{edges}

Criamos dois pics 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, optionalque 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 forestambiente.

\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 0e precisamos inverter a ordem dos filhos, caso contrário ela sairá de cabeça para baixo.

    grow'=0,

Aplique o folderestilo, que configura a pstreeestrutura 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. tikzO valor de especifica o código que será passado para o TikZ como está depois que a árvore for desenhada, mas antes do forestambiente 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 picadequadamente.

      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 picvariaçã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 optionalestilo.

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

árvore de diretórios com floresta v2

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.

  • \mkdirsizepara o tamanho base do ícone do diretório (largura = 12 x tamanho base);
  • touchsizepara o tamanho base do ícone do arquivo (largura = 8 x tamanho base);
  • \iconseppela distância entre o ícone e o nome;
  • \iconsepfrompathpara 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 pics sejam baseados nos valores de mkdir sizee touch size.

Também colocamos o ponto mais à esquerda de cada um picem x=0vez 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 sepe 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 picpara 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 picnã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 pathpois 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},
        },
      },
    },
  },

árvore de diretórios revisada com biblioteca **forest** <code>edges</code>

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}

Saída típica mostrando itens de árvore não padrão

informação relacionada