Tengo una PSTricks
implementación de un árbol de directorios personalizado que encuentro bastante atractivo. Básicamente quiero convertir todo a TikZ
. Logré ejecutar la idea muy básica TikZ
: puedo crear un directorio y un archivo. Pero no tengo idea de cómo colocarlos en relación con el elemento anterior. yo sé de ladirtree
paquete pero me gustan los símbolos para archivos y directorios.
En el código de PSTricks se agrega un nuevo párrafo \par
para cada nuevo elemento (archivo o directorio). Supongo que TikZ
tengo que colocar los nodos individuales entre sí. Por lo tanto, tengo que guardar el nombre o la ubicación del último nodo. ¿Cómo se puede hacer esto? ¿O hay otra forma completamente distinta?
Código PSTricks de trabajo
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 inicial de 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}
Archivos de imagen necesarios
Respuesta1
Me acabo de dar cuenta de que proporcionaste imágenes para los íconos. Oh bien. Aquí hay una solución pura de TikZ. Al menos, usabosqueque está basado en TikZ. Además, utiliza dos pic
s para los iconos, que luego se utilizan dentro del árbol.
Esto hace uso de la nueva edges
biblioteca parabosqueque incluye un folder
estilo para árboles de directorios. También puede dibujar las carpetas, pero no se parecen mucho a carpetas o archivos, por lo que probablemente no cumplan con sus expectativas. Aquí, el estilo sólo se utiliza para automatizar la apariencia estructural del árbol.
Esto esmuchomás fácil con la edges
biblioteca, ya que esto solía requerir la configuración de un estilo de árbol adecuado.
Cargar paquetes y la biblioteca que queramos.
\documentclass[tikz, border=10pt, multi]{standalone}
\usepackage{forest}
\useforestlibrary{edges}
\begin{document}
Aplique los valores predeterminados de la edges
biblioteca. Si planeas dibujar otros tipos de árboles, colócalo dentro de un grupo TeX para limitar el alcance.
\forestapplylibrarydefaults{edges}
Creamos dos pic
s para los iconos.
\tikzset{%
Para formas de carpetas, mkdir
.
mkdir/.pic={%
\draw [pic actions] (-1.5ex,-1ex) -- ++(0,2ex) -- ++(.25ex,.25ex) -- ++(1.25ex,0) -- ++(.25ex,-.25ex) -- ++(1.25ex,0) |- cycle;
},
Para formas de archivos, touch
.
touch/.pic={%
\draw [pic actions] (-1ex,-1.5ex) |- ++(1.25ex,3ex) edge ++(.75ex,-.75ex) |- ++(.75ex,-.75ex) |- cycle;
}
}
ahora unbosque-estilo específico, optional
que usaremos en lugar de \optional{}
.
\forestset{%
optional/.style={%
content/.wrap value={$<$\hspace{0.05em}\normalfont\itshape ##1\hspace{0.15em}$>$},
}
}
Pasemos ahora al árbol real, en el forest
medio ambiente.
\begin{forest}
Primero algo de personalización.
for tree={
Aplique esta configuración a todo el árbol.
font=\ttfamily,
Queremos que el árbol crezca hacia la derecha, es decir, en un ángulo 0
y necesitamos invertir el orden de los niños, de lo contrario saldrá al revés.
grow'=0,
Aplique el folder
estilo, que configura la pstree
estructura del tipo.
folder,
Todos los nodos terminales son archivos, mientras que todos los demás son directorios. Entonces, podemos agregar automáticamente los íconos probando si cada nodo tiene hijos (no terminal) o no (terminal).
if n children=0{
Necesitamos retrasar un poco el ajuste para que se establezca el contenido original. Luego agregaremos algo de espacio a la izquierda para dejar espacio para el ícono.
before typesetting nodes={
content/.wrap value={\hspace*{2.5ex}#1},
},
Agregaremos una anotación TikZ que dibujará el pic
ícono en el lugar relevante. tikz
El valor de especifica el código que se pasará a TikZ tal cual después de dibujar el árbol, pero antes de que forest
finalice el entorno. El contexto del nodo relevante todavía está disponible y podemos usarlo, por ejemplo, (.west)
para acceder al west
ancla del nodo actual para colocarlo pic
adecuadamente.
tikz={%
\pic [xshift=1.5ex] at (.west) {touch};
}
}{
Ahora hacemos lo mismo con los nodos no terminales. pic
Aquí sólo varían el espaciado y el espacio.
before typesetting nodes={
content/.wrap value={\hspace*{3.5ex}#1},
},
tikz={%
\pic [xshift=2ex] at (.west) {mkdir};
}
}
},
Ahora para el árbol en sí, comenzando con la raíz a la que queremos aplicar el optional
estilo.
[Project, optional
Primer subdirectorio
[Figures
y su contenido, que son nodos secundarios en el lenguaje de los árboles.
[fig-1.eps]
[fig-1.pdf]
[fig-1.png]
[fig-2.eps]
[fig-2.pdf]
[fig-2.png]
]
Finaliza el primer subdirectorio. Inicie el segundo subdirectorio, que es el segundo hijo del nodo raíz del árbol.
[Scripts
Y su contenido es infantil, como antes.
[install\_package\_A.sh]
[install\_package\_B.sh]
[install\_package\_C.sh]
]
Continúe agregando subdirectorios y sus contenidos.
[Sections
[section-1.tex]
[section-2.tex]
[section-3.tex]
[literature.bib]
]
Las dos últimas entradas están en el nivel justo debajo de la raíz, pero son archivos en sí mismos, es decir, hijos de la raíz que también son nodos terminales.
[project.kilepr]
[project.tex]
Cierra la raíz.
]
Y terminar el árbol.
\end{forest}
\end{document}
VERSIÓN REVISADA
Sin embargo, es posible que queramos más flexibilidad. Por ejemplo, es posible que queramos alterar más fácilmente el tamaño de los iconos/símbolos de los archivos y directorios, y controlar las distancias entre la ruta y el icono, por un lado, y el icono y el nombre, por el otro. .
Podemos hacer esto con un conjunto un poco más potente de configuraciones de TikZ y algunas modificaciones en elbosquecódigo. La parte más complicada de esto, para mí, resultó ser descubrir cómo usar múltiples dimensiones dentro forest
. Por ejemplo, cómo decirle que cambie algo 10 veces una longitud determinada o lo que sea. Finalmente, utilicé un registro de dimensiones cero para esto, pero no estoy seguro de que sea la solución más eficiente.
Empezamos, como antes, con algunas personalizaciones de TikZ.
\tikzset{%
Queremos que algunas macros contengan varias dimensiones para que puedan modificarse fácilmente. Usaremos 4 macros para esto.
\mkdirsize
para el tamaño base del icono del directorio (ancho = 12 x tamaño base);touchsize
para el tamaño base del icono del archivo (ancho = 8 x tamaño base);\iconsep
por la distancia entre el icono y el nombre;\iconsepfrompath
para la distancia entre la ruta y el icono.
Estos serán modificables como estilos TikZ.
mkdir size
;touch size
;icon sep
;icon sep from path
.
Aquí está la configuración:
mkdir size/.store in=\mkdirsize,
touch size/.store in=\touchsize,
icon sep/.store in=\iconsep,
icon sep from path/.store in=\iconsepfrompath,
Nos aseguramos de que todo tenga un valor predeterminado.
mkdir size=.25ex,
touch size=.25ex,
icon sep=1.5ex,
icon sep from path=1ex,
Ahora queremos que nuestra pic
s se base en los valores de mkdir size
y touch size
.
También colocamos el punto más a la izquierda de cada uno pic
en x=0
lugar de desplazarlo hacia la izquierda porque esto hace que sea más fácil ajustar correctamente la ubicación de los íconos dentro del árbol.
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;
},
}
También queremos adaptar el preámbulo del árbol para usar los valores de icon sep
y icon sep from path
.
\begin{forest}
Pero empezamos como antes.
for tree={
font=\ttfamily,
grow'=0,
folder,
Los cambios vienen al especificar dónde deben estar los nodos y el espacio que debe insertarse antes del contenido del nodo principal. Esta parte es con la que tuve problemas. Esto funciona, pero puede que no sea la solución más eficaz o eficiente.
if n children=0{
before typesetting nodes={
Usamos una dimensión de registro temporal para calcular cuánto espacio agregar al contenido del nodo.
tempdima=\iconsepfrompath+\iconsep+8*\touchsize,
content/.wrap value={\expandafter\hskip \foresteregister{tempdima}#1},
},
Luego también debemos desplazar el pic
hacia la derecha en la cantidad adecuada.
tikz={%
\pic [xshift=\iconsepfrompath] at (.west) {touch};
},
}{
Hay una complicación en el caso de los nodos del directorio, porque uno de estos está en la raíz y pic
no se debe mover aquí, y se debe agregar menos espacio al contenido del nodo. Así que trataremos este caso por separado.
if level=0{
No cambie el símbolo del directorio.
tikz={%
\pic at (.west) {mkdir};
},
Agregue el espacio al nodo, pero no agregue el valor de icon sep from path
ya que es irrelevante para el directorio raíz.
before typesetting nodes={
tempdima=\iconsep+12*\mkdirsize,
content/.wrap value={\expandafter\hskip \foresteregister{tempdima}#1},
},
Ahora para los directorios no raíz.
}{
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}
Respuesta2
Esto realmente no responde a tu pregunta, pero creo que es un diseño útil que se puede mantener y manipular fácilmente. También permite alguna estructura no estándar. Todavía no he descubierto cómo incluir íconos de archivos. También funciona mejor si mantienes las columnas de control de pestañas razonablemente bien alineadas.
\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}