ПЕРЕСМОТРЕННЫЙ ВАРИАНТ

ПЕРЕСМОТРЕННЫЙ ВАРИАНТ

У меня есть PSTricksреализация пользовательского дерева каталогов, которая мне кажется довольно привлекательной. По сути, я хочу преобразовать все это в TikZ. Мне удалось реализовать самую простую идею в TikZ: я могу создать каталог и файл. Но я понятия не имею, как расположить их относительно предыдущего элемента. Я знаю оdirtreepackage, но мне нравятся символы для файлов и каталогов.

В коде PSTricks добавляется новый параграф \parдля каждого нового элемента (файла или каталога). В TikZмне нужно позиционировать отдельные узлы относительно друг друга, я полагаю. Поэтому мне нужно сохранить имя или местоположение последнего узла. Как это можно сделать? Или есть совершенно другой способ?

Рабочий код PSTricks

Благодарности Дж. Стиру

Код:

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

Результат:

Результат PSTricks

Начальный код 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}

Необходимые файлы изображений

датаi.png заказ.png

решение1

Я только что понял, что вы предоставили изображения для иконок. О, ну. Вот чистое решение TikZ. По крайней мере, оно используетлескоторый основан на TikZ. Кроме того, он использует две pics для иконок, которые затем используются в дереве.

Это позволяет использовать новую edgesбиблиотеку длялескоторый включает folderстиль для деревьев каталогов. Он также может рисовать папки, но они не очень похожи на папки или файлы, поэтому, вероятно, не оправдают ваших ожиданий. Здесь стиль используется только для автоматизации структурного вида дерева.

Этомногопроще с edgesбиблиотекой, так как раньше для этого требовалась настройка подходящего стиля дерева.

Загружаем пакеты и нужную нам библиотеку.

\documentclass[tikz, border=10pt, multi]{standalone}
\usepackage{forest}
\useforestlibrary{edges}
\begin{document}

Применить значения по умолчанию из edgesбиблиотеки. Если вы планируете рисовать другие виды деревьев, поместите это в группу TeX, чтобы ограничить область действия.

\forestapplylibrarydefaults{edges}

Мы создаем две picбуквы S для иконок.

\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},
      },

Мы добавим аннотацию TikZ, которая отрисует picдля значка в соответствующем месте. 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}

дерево каталогов с лесом v2

ПЕРЕСМОТРЕННЫЙ ВАРИАНТ

Однако нам может понадобиться больше гибкости. Например, нам может понадобиться более простое изменение размера иконок/символов для файлов и каталогов, а также управление расстояниями между путем и иконкой, с одной стороны, и иконкой и именем, с другой.

Мы можем сделать это с помощью немного более мощного набора настроек TikZ и некоторых модификацийлесcode. Для меня самой сложной частью этого оказалось выяснить, как использовать кратные измерения внутри forest. Например, как сказать ему сдвинуть что-то на 10 раз больше определенной длины или что-то в этом роде. В конце концов, я использовал для этого регистр измерения scratch, но я не уверен, что это самое эффективное решение.

Начнем, как и прежде, с настройки 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,

Теперь мы хотим, чтобы наши pics основывались на значениях 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},
        },
      },
    },
  },

Измененное дерево каталогов с библиотекой **forest** <code>edges</code>

Полный код:

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

Типичный вывод, показывающий нестандартные элементы дерева

Связанный контент