89 lines
2.9 KiB
Python
Executable File
89 lines
2.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import argparse
|
|
from typing import List
|
|
|
|
p = argparse.ArgumentParser()
|
|
p.add_argument("file")
|
|
args = p.parse_args()
|
|
|
|
def _toc_from_file(path: str, add_indent=0) -> List[str]:
|
|
existing_ids = set()
|
|
|
|
INVALID_LINK_CHARS = ' /.()`'
|
|
|
|
def make_link(text: str) -> str:
|
|
text = text.lower().strip(INVALID_LINK_CHARS)
|
|
for char in INVALID_LINK_CHARS:
|
|
text = text.replace(char, '-')
|
|
|
|
while '--' in text:
|
|
text = text.replace('--', '-')
|
|
return text
|
|
|
|
output = []
|
|
with open(path, 'r') as file:
|
|
for line in file:
|
|
if line.startswith('<!-- TOC'):
|
|
command_argv = line.replace("<!-- TOC ", "").replace(" -->\n", "")
|
|
command, *args = command_argv.split(" ")
|
|
if command == 'BREAK':
|
|
print(f'Ignoring further TOC entries from ./{path}')
|
|
break
|
|
if not line.startswith('#'):
|
|
continue
|
|
line = line.strip('\r\n')
|
|
line_text = line.replace('#', '').lstrip()
|
|
line_indent = line.count('#') - 1
|
|
link = make_link(line_text)
|
|
spaces = ' ' * (line_indent + add_indent)
|
|
orig_link = link
|
|
i = 1
|
|
while link in existing_ids:
|
|
link = f'{orig_link}-{i}'
|
|
i += 1
|
|
existing_ids.add(link)
|
|
output.append(spaces * 3 + f'- [{line_text}](./{path}#{link})\n')
|
|
print(f'{path} - {len(output)} lines')
|
|
return output
|
|
|
|
|
|
def _toc_from_readme(path: str, add_indent=0) -> List[str]:
|
|
with open(path, 'r') as f:
|
|
lines = f.readlines()
|
|
files_to_read = []
|
|
output = []
|
|
has_started_removing = False
|
|
toc_entries = []
|
|
for line in lines:
|
|
if line.startswith("<!-- TOC"):
|
|
output.append(line)
|
|
command_argv = line.replace("<!-- TOC ", "").replace(" -->\n", "")
|
|
command, *args = command_argv.split(" ")
|
|
if command == 'FILES':
|
|
files_to_read = args
|
|
elif command == 'START':
|
|
has_started_removing = True
|
|
for filename in files_to_read:
|
|
temp = _toc_from_file(filename, add_indent)
|
|
toc_entries.extend(temp)
|
|
output.extend(temp)
|
|
if filename.endswith('readme.md'):
|
|
temp = _toc_from_readme(filename, add_indent + 1)
|
|
toc_entries.extend(temp)
|
|
output.extend(temp)
|
|
elif command == 'END':
|
|
has_started_removing = False
|
|
elif has_started_removing:
|
|
continue
|
|
else:
|
|
output.append(line)
|
|
with open(path, 'w') as f:
|
|
f.writelines(output)
|
|
print(f'Wrote {len(output)} lines to {path}.')
|
|
return toc_entries
|
|
|
|
if args.file.lower() == "readme.md":
|
|
_toc_from_readme(args.file)
|
|
else:
|
|
print(*_toc_from_file(args.file), sep='\n')
|