Skip to content

Commit 18dcfb2

Browse files
Update build_directory_md.py
1 parent a71618f commit 18dcfb2

File tree

1 file changed

+50
-33
lines changed

1 file changed

+50
-33
lines changed

scripts/build_directory_md.py

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,75 @@
11
#!/usr/bin/env python3
22

33
import os
4-
from collections.abc import Iterator
4+
import re
5+
from typing import Iterator, Set
56

67

8+
# Define directories to exclude during os.walk traversal
9+
EXCLUDED_DIRS: Set[str] = {"scripts", "venv", "__pycache__"}
10+
711
def good_file_paths(top_dir: str = ".") -> Iterator[str]:
812
for dir_path, dir_names, filenames in os.walk(top_dir):
913
dir_names[:] = [
1014
d
1115
for d in dir_names
12-
if d != "scripts" and d[0] not in "._" and "venv" not in d
16+
if d[0] not in "._" and d not in EXCLUDED_DIRS
1317
]
1418
for filename in filenames:
1519
if filename == "__init__.py":
1620
continue
17-
if os.path.splitext(filename)[1] in (".py", ".ipynb"):
18-
yield os.path.join(dir_path, filename).lstrip("./")
1921

22+
# Check for valid extensions
23+
_, ext = os.path.splitext(filename)
24+
if ext in (".py", ".ipynb"):
25+
# Clean up path to ensure it doesn't start with './'
26+
full_path = os.path.join(dir_path, filename)
27+
yield full_path.lstrip("./")
28+
29+
def _generate_markdown_prefix(indent_level: int) -> str:
30+
if indent_level == 0:
31+
# Markdown H2 header for root-level entries
32+
return "\n##"
33+
# Indent with 2 spaces per level for nested lists (e.g., 2 spaces for level 1, 4 for level 2)
34+
return f"{' ' * (indent_level * 2)}*"
2035

21-
def md_prefix(indent: int) -> str:
36+
def _format_name(name: str) -> str:
2237
"""
23-
Markdown prefix based on indent for bullet points
24-
25-
>>> md_prefix(0)
26-
'\\n##'
27-
>>> md_prefix(1)
28-
' *'
29-
>>> md_prefix(2)
30-
' *'
31-
>>> md_prefix(3)
32-
' *'
38+
Converts a file/directory name (e.g., 'my_awesome_file') into a Title Case
39+
string, replacing underscores with spaces (e.g., 'My Awesome File').
3340
"""
34-
return f"{indent * ' '}*" if indent else "\n##"
35-
41+
return name.replace('_', ' ').title()
3642

37-
def print_path(old_path: str, new_path: str) -> str:
38-
old_parts = old_path.split(os.sep)
39-
for i, new_part in enumerate(new_path.split(os.sep)):
40-
if (i + 1 > len(old_parts) or old_parts[i] != new_part) and new_part:
41-
print(f"{md_prefix(i)} {new_part.replace('_', ' ').title()}")
42-
return new_path
4343

4444

4545
def print_directory_md(top_dir: str = ".") -> None:
46-
old_path = ""
47-
for filepath in sorted(good_file_paths(top_dir)):
48-
filepath, filename = os.path.split(filepath)
49-
if filepath != old_path:
50-
old_path = print_path(old_path, filepath)
51-
indent = (filepath.count(os.sep) + 1) if filepath else 0
52-
url = f"{filepath}/{filename}".replace(" ", "%20")
53-
filename = os.path.splitext(filename.replace("_", " ").title())[0]
54-
print(f"{md_prefix(indent)} [{filename}]({url})")
46+
# Stores the path of the last directory printed to determine new structure levels
47+
last_printed_path = ""
48+
# Get and sort all file paths to ensure consistent output order
49+
sorted_file_paths = sorted(good_file_paths(top_dir))
50+
51+
for filepath in sorted_file_paths:
52+
current_dir_path, filename = os.path.split(filepath)
53+
if current_dir_path != last_printed_path:
54+
old_parts = last_printed_path.split(os.sep)
55+
new_parts = current_dir_path.split(os.sep)
56+
57+
i = 0
58+
while i < len(old_parts) and i < len(new_parts) and old_parts[i] == new_parts[i]:
59+
i += 1
60+
for indent, new_part in enumerate(new_parts[i:], start=i):
61+
if new_part: # Ensure we don't print empty segments
62+
prefix = _generate_markdown_prefix(indent)
63+
print(f"{prefix} {_format_name(new_part)}")
64+
last_printed_path = current_dir_path
65+
indent = (current_dir_path.count(os.sep) + 1) if current_dir_path else 0
66+
67+
url = filepath.replace(" ", "%20")
68+
display_name = os.path.splitext(_format_name(filename))[0]
69+
70+
prefix = _generate_markdown_prefix(indent)
71+
print(f"{prefix} [{display_name}]({url})")
5572

5673

5774
if __name__ == "__main__":
58-
print_directory_md(".")
75+
print_directory_md()

0 commit comments

Comments
 (0)