改訂版

改訂版

私は非常に魅力的なカスタムディレクトリツリーの実装を持っています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}

結果:

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}

必要な画像ファイル

日付.png オーダー.png

答え1

アイコンに画像を用意したことに気づきました。ああ、いいでしょう。純粋なTikZソリューションをご紹介します。少なくとも、これは TikZ に基づいています。さらに、picツリー内で使用されるアイコンに 2 つの を使用します。

これは新しいedgesライブラリを利用してディレクトリ ツリーのスタイルが含まれていますfolder。フォルダーも描画できますが、フォルダーやファイルとはまったく似ていないため、期待に沿わない可能性があります。ここでは、スタイルはツリーの構造的な外観を自動化するためにのみ使用されます。

これは多くのedges以前は適切なツリー スタイルを設定する必要がありましたが、ライブラリを使用すると簡単になります。

必要なパッケージとライブラリをロードします。

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

ライブラリからデフォルトを適用しますedges。他の種類のツリーを描画する予定の場合は、これを TeX グループ内に配置して範囲を制限します。

\forestapplylibrarydefaults{edges}

picアイコン用に2 つの を作成します。

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

スタイルを適用してfolderpstree型構造を設定します。

    folder,

ターミナルノードはすべてファイルですが、その他はすべてディレクトリです。したがって、各ノードに子ノードがあるかどうか (非ターミナル)、またはないかどうか (ターミナル) をテストすることで、アイコンを自動的に追加できます。

    if n children=0{

調整を少し遅らせて、元のコンテンツを設定します。次に、アイコン用のスペースを確保するために左側にスペースを追加します。

      before typesetting nodes={
        content/.wrap value={\hspace*{2.5ex}#1},
      },

pic関連する場所にアイコンの を描画する TikZ アノテーションを追加します。tikzの値は、ツリーが描画された後、forest環境が終了する前にそのまま TikZ に渡されるコードを指定します。 関連するノードのコンテキストはまだ使用可能であり、を適切に配置するために、たとえば を使用して現在のノードのアンカー(.west)にアクセスできます。westpic

      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]
    ]

最初のサブディレクトリを終了します。ツリーのルート ノードの 2 番目の子である 2 番目のサブディレクトリを開始します。

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

最後の 2 つのエントリはルートのすぐ下のレベルにありますが、これら自体がファイルであり、つまりルートの子であり、ターミナル ノードでもあります。

    [project.kilepr]
    [project.tex]

ルートを閉じます。

  ]

そして木を完成させます。

\end{forest}
\end{document}

フォレスト v2 のディレクトリ ツリー

改訂版

しかし、もっと柔軟性が欲しいと思うかもしれません。たとえば、ファイルやディレクトリのアイコンやシンボルのサイズをもっと簡単に変更したり、一方ではパスとアイコン、他方ではアイコンと名前の間の距離を制御したりしたいかもしれません。

これを、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,

ここで、 をとpicの値に基づいて設定します。mkdir sizetouch size

また、各アイコンの左端のポイントを左にシフトするのではなく に配置するpicx=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};
      },
    }{

ディレクトリ ノードの場合は複雑です。ディレクトリ ノードの 1 つはルートにあり、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}

非標準のツリー項目を示す典型的な出力

関連情報