經過修改的版本

經過修改的版本

我有PSTricks一個自訂目錄樹的實現,我覺得它非常有吸引力。我基本上想將整個事情轉換為TikZ.我設法實現了非常基本的想法TikZ:我可以建立一個目錄和一個檔案。但我不知道如何將它們相對於前一個項目定位。我確實知道dirtree包,但我確實喜歡文件和目錄的符號。

\par在 PSTricks 程式碼中,為每個新項目(檔案或目錄)新增一個段落。我猜我確實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}

結果:

PST技巧結果

初始 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 的。此外,它使用兩個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相關節點的上下文仍然可用,我們可以使用eg(.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 設定和對森林代碼。對我來說,最棘手的部分是弄清楚如何在 內部使用多個維度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,

現在我們希望我們的pics 基於mkdir size和的值touch 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};
      },
    }{

目錄節點的情況比較複雜,因為其中一個位於根目錄,不應該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}

顯示非標準樹項目的典型輸出

相關內容