This article walks through the output features of
printtree.
demo <- file.path(tempdir(), "printtree-feature-tour")
if (dir.exists(demo)) unlink(demo, recursive = TRUE, force = TRUE)
dir.create(file.path(demo, "R"), recursive = TRUE)
dir.create(file.path(demo, "data", "raw"), recursive = TRUE)
dir.create(file.path(demo, "logs"), recursive = TRUE)
dir.create(file.path(demo, "empty"), recursive = TRUE)
file.create(file.path(demo, "R", "helpers.R"))
#> [1] TRUE
file.create(file.path(demo, "README.md"))
#> [1] TRUE
file.create(file.path(demo, "data", "raw", "sales.csv"))
#> [1] TRUE
file.create(file.path(demo, "logs", "debug.log"))
#> [1] TRUE
file.create(file.path(demo, "test_cache"))
#> [1] TRUEBy default, print_rtree() ends with a displayed
directory/file count.
print_rtree(demo, max_depth = 2)
#> printtree-feature-tour/
#> |-- data/
#> | `-- raw/
#> |-- empty/
#> |-- logs/
#> | `-- debug.log
#> |-- R/
#> | `-- helpers.R
#> |-- README.md
#> `-- test_cache
#>
#> 5 directories, 4 filesSet count_footer = FALSE for compact output.
The ignore argument still supports exact basenames, but
with ignore_type = "auto" it also treats wildcard entries
as glob patterns.
print_rtree(demo, ignore = c("*.log", "test_*"), max_depth = 2)
#> printtree-feature-tour/
#> |-- data/
#> | `-- raw/
#> |-- empty/
#> |-- logs/
#> |-- R/
#> | `-- helpers.R
#> `-- README.md
#>
#> 5 directories, 2 filesYou can opt into regular expression matching for more control.
Use prune = TRUE to hide directories with no displayable
children after ignores and depth limits are applied.
Use quiet = TRUE with return_lines = TRUE
when you want to work with the tree programmatically.
write_tree() writes the same tree output to a text or
Markdown file. Parent directories are created automatically by
default.
tree_md <- file.path(tempdir(), "printtree-feature-tour-output", "tree.md")
write_tree(demo, tree_md, format = "md", title = "Feature Tour Tree")
readLines(tree_md, n = 8)#> [1] "# Feature Tour Tree" ""
#> [3] "```" "printtree-feature-tour/"
#> [5] "|-- data/" "| `-- raw/"
#> [7] "| `-- sales.csv" "|-- empty/"
tree_to_mermaid() and tree_to_dot() convert
the tree to diagram text that renders in Quarto documents: Mermaid
flowcharts render natively in {mermaid} chunks (and on
GitHub), while DOT graphs render in {dot} chunks when
Graphviz is installed. Both accept the same filtering options as the
printed tree (ignore, max_depth,
show_hidden, prune).
flowchart TD
n1(["printtree-feature-tour/"])
n2(["raw/"])
n3(["data/"])
n4(["empty/"])
n5["debug.log"]
n6(["logs/"])
n7["helpers.R"]
n8(["R/"])
n9["README.md"]
n10["test_cache"]
n3 --> n2
n1 --> n3
n1 --> n4
n6 --> n5
n1 --> n6
n8 --> n7
n1 --> n8
n1 --> n9
n1 --> n10
Use view_mermaid() for the same rendered preview from an
interactive R session. The viewer includes pan/zoom controls for large
trees and browser-side SVG, PNG, and JPEG download buttons. The raw
Mermaid source remains available from
tree_to_mermaid().
For automation, save writes a clean rendered image
without the viewer toolbar. PNG, JPEG, and PDF export require the
suggested webshot2 package and a Chrome/Chromium browser. A
missing extension is appended automatically; an explicit extension must
match save.
view_mermaid(demo, file = "tree.png", save = "png", open = FALSE)
view_mermaid(demo, file = "tree.pdf", save = "pdf", open = FALSE)These examples are not evaluated while building the vignette, so package and CRAN checks never launch a browser. Mermaid itself is loaded from a public CDN, which means the viewer and rendered export require an internet connection.
cat(tree_to_dot(demo, max_depth = 2))
#> digraph printtree {
#> rankdir=TB;
#> node [fontname="Helvetica"];
#> "n1" [label="printtree-feature-tour/", shape=folder];
#> "n2" [label="raw/", shape=folder];
#> "n3" [label="data/", shape=folder];
#> "n4" [label="empty/", shape=folder];
#> "n5" [label="debug.log", shape=note];
#> "n6" [label="logs/", shape=folder];
#> "n7" [label="helpers.R", shape=note];
#> "n8" [label="R/", shape=folder];
#> "n9" [label="README.md", shape=note];
#> "n10" [label="test_cache", shape=note];
#> "n3" -> "n2";
#> "n1" -> "n3";
#> "n1" -> "n4";
#> "n6" -> "n5";
#> "n1" -> "n6";
#> "n8" -> "n7";
#> "n1" -> "n8";
#> "n1" -> "n9";
#> "n1" -> "n10";
#> }write_tree() can write either diagram format directly,
or produce a minimal Quarto document with the tree embedded as a Mermaid
diagram:
tree_qmd <- file.path(tempdir(), "printtree-feature-tour-output", "tree.qmd")
write_tree(demo, tree_qmd, format = "qmd", title = "Feature Tour Tree",
max_depth = 2)
readLines(tree_qmd, n = 12)#> [1] "---"
#> [2] "title: 'Feature Tour Tree'"
#> [3] "---"
#> [4] ""
#> [5] "```{mermaid}"
#> [6] "flowchart TD"
#> [7] " n1([\"printtree-feature-tour/\"])"
#> [8] " n2([\"raw/\"])"
#> [9] " n3([\"data/\"])"
#> [10] " n4([\"empty/\"])"
#> [11] " n5[\"debug.log\"]"
#> [12] " n6([\"logs/\"])"
The diagram functions have a few more tricks.
git_colors = TRUE tints nodes by Git status (amber =
modified, green = untracked, blue = staged),
subgraph = TRUE wraps each directory in a Mermaid subgraph
container, and repo_url makes every node clickable, linking
to the file or directory on GitHub:
cat(tree_to_mermaid(demo, max_depth = 2, git_colors = TRUE, subgraph = TRUE,
repo_url = "https://github.com/PrigasG/printtree"))
#> flowchart TD
#> subgraph n1["printtree-feature-tour/"]
#> subgraph n3["data/"]
#> subgraph n2["raw/"]
#> end
#> end
#> subgraph n4["empty/"]
#> end
#> subgraph n6["logs/"]
#> n5["debug.log"]
#> end
#> subgraph n8["R/"]
#> n7["helpers.R"]
#> end
#> n9["README.md"]
#> n10["test_cache"]
#> end
#> click n1 "https://github.com/PrigasG/printtree/tree/main"
#> click n2 "https://github.com/PrigasG/printtree/tree/main/data/raw"
#> click n3 "https://github.com/PrigasG/printtree/tree/main/data"
#> click n4 "https://github.com/PrigasG/printtree/tree/main/empty"
#> click n5 "https://github.com/PrigasG/printtree/blob/main/logs/debug.log"
#> click n6 "https://github.com/PrigasG/printtree/tree/main/logs"
#> click n7 "https://github.com/PrigasG/printtree/blob/main/R/helpers.R"
#> click n8 "https://github.com/PrigasG/printtree/tree/main/R"
#> click n9 "https://github.com/PrigasG/printtree/blob/main/README.md"
#> click n10 "https://github.com/PrigasG/printtree/blob/main/test_cache"
#> n3 --> n2
#> n1 --> n3
#> n1 --> n4
#> n6 --> n5
#> n1 --> n6
#> n8 --> n7
#> n1 --> n8
#> n1 --> n9
#> n1 --> n10tree_to_mindmap() renders the same tree as a radial
Mermaid mindmap, and tree_to_html() produces a
self-contained HTML page with click-to-expand directories (no external
dependencies):
cat(tree_to_mindmap(demo, max_depth = 2))
#> mindmap
#> root((printtree-feature-tour/))
#> data/
#> raw/
#> empty/
#> logs/
#> debug.log
#> R/
#> helpers.R
#> README.md
#> test_cachetree_html <- file.path(tempdir(), "printtree-feature-tour-output", "tree.html")
write_tree(demo, tree_html, format = "html", title = "Feature Tour Tree",
max_depth = 2)Finally, tree_diff_mermaid() and
tree_diff_dot() compare two directory trees: nodes only in
the second tree are green, nodes only in the first are red and
dashed.
To use the output in your own Quarto document, generate the diagram
once and paste it into a {mermaid} chunk — or let
write_tree() produce the whole Quarto document for you:
When the target folder is inside a Git work tree,
git = TRUE annotates changed paths with simple status
markers and includes a legend.
repo <- file.path(tempdir(), "printtree-feature-tour-git")
if (dir.exists(repo)) unlink(repo, recursive = TRUE, force = TRUE)
dir.create(repo, recursive = TRUE)
system2("git", c("-C", repo, "init"), stdout = FALSE, stderr = FALSE)
system2("git", c("-C", repo, "config", "user.email", "[email protected]"))
system2("git", c("-C", repo, "config", "user.name", "Test User"))
file.create(file.path(repo, "tracked.txt"))
system2("git", c("-C", repo, "add", "tracked.txt"), stdout = FALSE, stderr = FALSE)
system2("git", c("-C", repo, "commit", "-m", "initial"), stdout = FALSE, stderr = FALSE)
writeLines("changed", file.path(repo, "tracked.txt"))
file.create(file.path(repo, "new.txt"))
print_rtree(repo, git = TRUE)