Skip to content

Commit 0dd110d

Browse files
committed
docs: Update TOC.md files to include 'Table of Contents' in headers and improve content generation logic
1 parent ed82bc6 commit 0dd110d

File tree

5 files changed

+319
-266
lines changed

5 files changed

+319
-266
lines changed

.scripts/idxtool.py

+144-91
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,9 @@ def rebuild_toc(toc_out: str = '') -> Tuple[bool, str]:
8888
if not toc_out:
8989
toc_out = toc_in
9090

91-
# Open the output file for writing (overwriting any existing content)
92-
try:
93-
ofile = open(toc_out, 'w', encoding='utf-8')
94-
except:
95-
return (False, f"Failed to open '{toc_out}' for writing.")
96-
97-
# Write a header for the TOC file
91+
# Generate new TOC content
9892
out = []
99-
out.append("# ChatGPT System Prompts \n\n")
93+
out.append("# ChatGPT System Prompts - Table of Contents\n\n")
10094
out.append("This document contains a table of contents for the ChatGPT System Prompts repository.\n\n")
10195

10296
# Add links to TOC.md files in prompts directory subdirectories
@@ -112,17 +106,36 @@ def rebuild_toc(toc_out: str = '') -> Tuple[bool, str]:
112106

113107
if prompt_dirs:
114108
out.append("## Prompt Collections\n\n")
115-
prompt_dirs.sort() # Sort alphabetically
109+
prompt_dirs.sort(key=str.lower) # Sort alphabetically case-insensitive
116110
for dirname in prompt_dirs:
117111
# Create a relative link to the subdirectory TOC file
118112
link = f"./prompts/{dirname}/{TOC_FILENAME}"
119113
out.append(f"- [{dirname} Collection]({link})\n")
120114

121-
ofile.writelines(out)
122-
ofile.close()
123-
msg = f"Generated TOC with Prompt Collections only."
115+
# Combine into a single string
116+
new_content = ''.join(out)
124117

125-
return (True, msg)
118+
# Check if the file exists and if its content matches the new content
119+
if os.path.exists(toc_out):
120+
try:
121+
with open(toc_out, 'r', encoding='utf-8') as existing_file:
122+
existing_content = existing_file.read()
123+
if existing_content == new_content:
124+
msg = f"TOC content unchanged, skipping write to '{toc_out}'"
125+
print(msg)
126+
return (True, msg)
127+
except Exception as e:
128+
print(f"Warning: Could not read existing TOC file: {str(e)}")
129+
130+
# Content is different or file doesn't exist, write the new content
131+
try:
132+
with open(toc_out, 'w', encoding='utf-8') as ofile:
133+
ofile.write(new_content)
134+
msg = f"Generated TOC with Prompt Collections only."
135+
return (True, msg)
136+
except Exception as e:
137+
msg = f"Failed to write TOC file: {str(e)}"
138+
return (False, msg)
126139

127140
def make_template(url, verbose=True):
128141
"""Creates an empty GPT template file from a ChatGPT URL"""
@@ -305,47 +318,67 @@ def generate_gpts_toc(dir_path):
305318
A tuple (success, message) indicating success/failure and a descriptive message
306319
"""
307320
toc_path = os.path.join(dir_path, TOC_FILENAME)
321+
322+
# Generate new content
308323
try:
309-
with open(toc_path, 'w', encoding='utf-8') as toc_file:
310-
toc_file.write(f"# gpts \n\n")
311-
312-
# Count GPTs
313-
enumerated_gpts = list(enum_gpts())
314-
nb_ok = sum(1 for ok, gpt in enumerated_gpts if ok and gpt.id())
315-
316-
toc_file.write(f"## GPTs ({nb_ok} total)\n\n")
317-
318-
nb_ok = nb_total = 0
319-
gpts = []
320-
for ok, gpt in enumerated_gpts:
321-
nb_total += 1
322-
if ok:
323-
if gpt_id := gpt.id():
324-
nb_ok += 1
325-
gpts.append((gpt_id, gpt))
326-
else:
327-
print(f"[!] No ID detected: {gpt.filename}")
324+
out = []
325+
out.append(f"# gpts - Table of Contents\n\n")
326+
327+
# Count GPTs
328+
enumerated_gpts = list(enum_gpts())
329+
nb_ok = sum(1 for ok, gpt in enumerated_gpts if ok and gpt.id())
330+
331+
out.append(f"## GPTs ({nb_ok} total)\n\n")
332+
333+
nb_ok = nb_total = 0
334+
gpts = []
335+
for ok, gpt in enumerated_gpts:
336+
nb_total += 1
337+
if ok:
338+
if gpt_id := gpt.id():
339+
nb_ok += 1
340+
gpts.append((gpt_id, gpt))
328341
else:
329-
print(f"[!] {gpt}")
330-
331-
# Consistently sort the GPTs by title
332-
def gpts_sorter(key):
333-
gpt_id, gpt = key
334-
version = f"{gpt.get('version')}" if gpt.get('version') else ''
335-
return f"{gpt.get('title')}{version} (id: {gpt_id.id}))"
336-
gpts.sort(key=gpts_sorter)
337-
338-
for id, gpt in gpts:
339-
file_link = f"./{quote(os.path.basename(gpt.filename))}"
340-
version = f" {gpt.get('version')}" if gpt.get('version') else ''
341-
toc_file.write(f"- [{gpt.get('title')}{version} (id: {id.id})]({file_link})\n")
342+
print(f"[!] No ID detected: {gpt.filename}")
343+
else:
344+
print(f"[!] {gpt}")
345+
346+
# Consistently sort the GPTs by title
347+
def gpts_sorter(key):
348+
gpt_id, gpt = key
349+
version = f"{gpt.get('version')}" if gpt.get('version') else ''
350+
return f"{gpt.get('title', '').lower()}{version} (id: {gpt_id.id}))" # Case-insensitive sort
351+
gpts.sort(key=gpts_sorter)
352+
353+
for id, gpt in gpts:
354+
file_link = f"./{quote(os.path.basename(gpt.filename))}"
355+
version = f" {gpt.get('version')}" if gpt.get('version') else ''
356+
out.append(f"- [{gpt.get('title')}{version} (id: {id.id})]({file_link})\n")
357+
358+
new_content = ''.join(out)
359+
360+
# Check if the file exists and if its content matches the new content
361+
if os.path.exists(toc_path):
362+
try:
363+
with open(toc_path, 'r', encoding='utf-8') as existing_file:
364+
existing_content = existing_file.read()
365+
if existing_content == new_content:
366+
msg = f"TOC content unchanged for 'gpts', skipping write"
367+
print(msg)
368+
return (True, msg)
369+
except Exception as e:
370+
print(f"Warning: Could not read existing gpts TOC file: {str(e)}")
371+
372+
# Content is different or file doesn't exist, write the new content
373+
with open(toc_path, 'w', encoding='utf-8') as toc_file:
374+
toc_file.write(new_content)
342375

343376
return (True, f"Generated TOC.md for 'gpts' with {nb_ok} out of {nb_total} GPTs.")
344377
except Exception as e:
345378
return (False, f"Error generating TOC.md for 'gpts': {str(e)}")
346379

347380
# Process each top-level directory under prompts/
348-
for dirname in sorted(all_dirs): # Sort for consistent processing order
381+
for dirname in sorted(all_dirs, key=str.lower): # Sort for consistent processing order
349382
dir_path = os.path.join(prompts_base_path, dirname)
350383
if not os.path.isdir(dir_path):
351384
messages.append(f"Directory '{dirname}' does not exist, skipping")
@@ -370,52 +403,72 @@ def gpts_sorter(key):
370403
# Generate TOC.md for this directory
371404
toc_path = os.path.join(dir_path, TOC_FILENAME)
372405
try:
406+
# Generate new content
407+
out = []
408+
out.append(f"# {dirname} - Table of Contents\n\n")
409+
410+
# Group files by their subdirectory
411+
files_by_dir = {}
412+
for rel_dir_path, filename, title in md_files:
413+
if rel_dir_path not in files_by_dir:
414+
files_by_dir[rel_dir_path] = []
415+
files_by_dir[rel_dir_path].append((filename, title))
416+
417+
# First list files in the root directory
418+
if '' in files_by_dir:
419+
root_files = files_by_dir['']
420+
root_files.sort(key=lambda x: x[1].lower()) # Sort alphabetically by title, case-insensitive
421+
422+
for filename, title in root_files:
423+
out.append(f"- [{title}](./{quote(filename)})\n")
424+
425+
# Add a separator if we have subdirectories
426+
if len(files_by_dir) > 1:
427+
out.append("\n")
428+
429+
# Then list files in subdirectories
430+
subdirs = [d for d in files_by_dir.keys() if d != '']
431+
if subdirs:
432+
out.append("## Subdirectories\n\n")
433+
434+
# Sort subdirectories alphabetically, case-insensitive
435+
subdirs.sort(key=str.lower)
436+
437+
for subdir in subdirs:
438+
# Write the subdirectory name as a heading
439+
display_subdir = subdir.replace('\\', '/') # Ensure consistent path display
440+
out.append(f"### {display_subdir}\n\n")
441+
442+
# Sort files in this subdirectory alphabetically by title, case-insensitive
443+
subdir_files = files_by_dir[subdir]
444+
subdir_files.sort(key=lambda x: x[1].lower())
445+
446+
for filename, title in subdir_files:
447+
# Create a link with the correct relative path to the file
448+
# Use os.path.join for correct path construction then replace backslashes for display
449+
link_path = os.path.join(subdir, filename).replace('\\', '/')
450+
out.append(f"- [{title}](./{quote(link_path)})\n")
451+
452+
out.append("\n")
453+
454+
new_content = ''.join(out)
455+
456+
# Check if the file exists and if its content matches the new content
457+
if os.path.exists(toc_path):
458+
try:
459+
with open(toc_path, 'r', encoding='utf-8') as existing_file:
460+
existing_content = existing_file.read()
461+
if existing_content == new_content:
462+
msg = f"TOC content unchanged for '{dirname}', skipping write"
463+
print(msg)
464+
messages.append(msg)
465+
continue # Skip to next directory
466+
except Exception as e:
467+
print(f"Warning: Could not read existing TOC file for '{dirname}': {str(e)}")
468+
469+
# Content is different or file doesn't exist, write the new content
373470
with open(toc_path, 'w', encoding='utf-8') as toc_file:
374-
toc_file.write(f"# {dirname} \n\n")
375-
376-
# Group files by their subdirectory
377-
files_by_dir = {}
378-
for rel_dir_path, filename, title in md_files:
379-
if rel_dir_path not in files_by_dir:
380-
files_by_dir[rel_dir_path] = []
381-
files_by_dir[rel_dir_path].append((filename, title))
382-
383-
# First list files in the root directory
384-
if '' in files_by_dir:
385-
root_files = files_by_dir['']
386-
root_files.sort() # Sort alphabetically
387-
388-
for filename, title in root_files:
389-
toc_file.write(f"- [{title}](./{quote(filename)})\n")
390-
391-
# Add a separator if we have subdirectories
392-
if len(files_by_dir) > 1:
393-
toc_file.write("\n")
394-
395-
# Then list files in subdirectories
396-
subdirs = [d for d in files_by_dir.keys() if d != '']
397-
if subdirs:
398-
toc_file.write("## Subdirectories\n\n")
399-
400-
# Sort subdirectories alphabetically
401-
subdirs.sort()
402-
403-
for subdir in subdirs:
404-
# Write the subdirectory name as a heading
405-
display_subdir = subdir.replace('\\', '/') # Ensure consistent path display
406-
toc_file.write(f"### {display_subdir}\n\n")
407-
408-
# Sort files in this subdirectory alphabetically
409-
subdir_files = files_by_dir[subdir]
410-
subdir_files.sort()
411-
412-
for filename, title in subdir_files:
413-
# Create a link with the correct relative path to the file
414-
# Use os.path.join for correct path construction then replace backslashes for display
415-
link_path = os.path.join(subdir, filename).replace('\\', '/')
416-
toc_file.write(f"- [{title}](./{quote(link_path)})\n")
417-
418-
toc_file.write("\n")
471+
toc_file.write(new_content)
419472

420473
messages.append(f"Generated TOC.md for '{dirname}' with {len(md_files)} total files")
421474

TOC.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# ChatGPT System Prompts
1+
# ChatGPT System Prompts - Table of Contents
22

33
This document contains a table of contents for the ChatGPT System Prompts repository.
44

0 commit comments

Comments
 (0)