diff options
Diffstat (limited to 'repo')
| -rw-r--r-- | repo/www/Makefile | 9 | ||||
| -rw-r--r-- | repo/www/TODO | 2 | ||||
| -rw-r--r-- | repo/www/helpers.py | 37 | ||||
| -rwxr-xr-x | repo/www/make-deps.py | 77 | ||||
| -rwxr-xr-x | repo/www/make-index.py | 55 |
5 files changed, 130 insertions, 50 deletions
diff --git a/repo/www/Makefile b/repo/www/Makefile index 8f5bb2a..e7d5184 100644 --- a/repo/www/Makefile +++ b/repo/www/Makefile @@ -18,14 +18,19 @@ include $(dependencies) $(dependencies): make-deps.py $(text_folders) python3 $< "$(TEXT_FILES)" $(OUT_DIR) -site: $(pages) +site: $(pages) $(autoindices) $(page_folders): mkdir -p $@ -%.html: +$(pages): pandoc -s $< -o $@ +# ⚠ When tweaking this rule, check whether it still works for the +# top-level index.html, i.e. when there is no top-level README. +$(autoindices): $(OUT_DIR)%/index.html: $(TOP_DIR)% make-index.py | $(OUT_DIR)% + python3 make-index.py "$(TEXT_FILES)" "$(*:/%=%)" $(OUT_DIR) + clean: -rm $(dependencies) -rm -r $(OUT_DIR) diff --git a/repo/www/TODO b/repo/www/TODO index eb63cd2..a6b2bf6 100644 --- a/repo/www/TODO +++ b/repo/www/TODO @@ -1,5 +1,5 @@ - compute "leak count" on toplevel index -- autogenerate index.html's for folders lacking READMEs +- add index to READMEs - autogenerate nav - autogenerate breadcrumbs - get stylin' diff --git a/repo/www/helpers.py b/repo/www/helpers.py new file mode 100644 index 0000000..57f679d --- /dev/null +++ b/repo/www/helpers.py @@ -0,0 +1,37 @@ +from collections import defaultdict +from dataclasses import dataclass, field +from os import path +from typing import List, Set + + +@dataclass +class Directory: + files: List[str] = field(default_factory=list) + subfolders: Set[str] = field(default_factory=set) + + +def _find_files(extensions, repository): + patterns = (f'**.{ext}' for ext in extensions) + zero = '\x00' + return repository.git.ls_files('-z', *patterns).strip(zero).split(zero) + + +def _fill_directories(files, top_dir): + directories = defaultdict(Directory) + + for f in files: + fdir, fname = path.split(f) + + directories[fdir].files.append(fname) + + if fdir: + parent, child = path.split(fdir) + directories[parent].subfolders.add(child) + + return directories + + +def compute_directories(extensions, repository): + files = _find_files(extensions, repository) + top_dir = path.relpath(repository.working_dir, path.curdir) + return _fill_directories(files, top_dir) diff --git a/repo/www/make-deps.py b/repo/www/make-deps.py index c2a88e1..b7c71d7 100755 --- a/repo/www/make-deps.py +++ b/repo/www/make-deps.py @@ -6,30 +6,18 @@ We want to compute: - a list of leaf pages, - a list of auto-generated indices, - - dependencies for leaf pages: OUTPUT/foo/bar.html: foo/bar.txt | OUTPUT/foo - - special case for READMEs: OUTPUT/foo/index.html: foo/README.txt foo | OUTPUT/foo - -- dependencies for auto-generated indices: - OUTPUT/foo/index.html: foo | OUTPUT/foo """ -from collections import defaultdict -from dataclasses import dataclass, field from os import path from sys import argv, exit -from typing import List, Set from git import Repo - -@dataclass -class Directory: - files: List[str] = field(default_factory=list) - subfolders: Set[str] = field(default_factory=set) +from helpers import compute_directories def parse_arguments(args): @@ -39,62 +27,57 @@ def parse_arguments(args): return argv[1].split(), argv[2] -def find_sources(extensions, repository): - patterns = (f'**.{ext}' for ext in extensions) - zero = '\x00' - return repository.git.ls_files('-z', *patterns).strip(zero).split(zero) - - -def compute_directories(files, top_dir): - directories = defaultdict(Directory) - - for f in files: - fdir, fname = path.split(f) - - directories[fdir].files.append(fname) - - if fdir: - parent, child = path.split(fdir) - directories[parent].subfolders.add(child) +def pjoin(directory, item): + return ( + path.join(directory, item) + if item # Avoid trailing slash for top-level files. + else directory + ) - return directories - -def write_dependencies(deps, directories, top_dir, out_dir): +def write_dependencies(deps_file, directories, top_dir, out_dir): pages = list() + autoindices = list() for dpath, d in directories.items(): + autoindex = True + + src_dir = pjoin(top_dir, dpath) for f in d.files: + src_path = path.join(src_dir, f) + name, _ = path.splitext(f) + deps = [src_path] + if name == 'README': name = 'index' + deps.append(src_dir) + autoindex = False - html_dir = ( - path.join(out_dir, dpath) - if dpath - else out_dir - ) - + html_dir = pjoin(out_dir, dpath) html_path = path.join(html_dir, name+'.html') - src_path = path.join(top_dir, dpath, f) - print(f'{html_path}: {src_path} | {html_dir}', file=deps) + print(f'{html_path}: {" ".join(deps)} | {html_dir}', file=deps_file) pages.append(html_path) - print(file=deps) - print(f'pages = {" ".join(pages)}', file=deps) + if autoindex: + autoindices.append( + path.join(out_dir, dpath, 'index.html') + ) + + print(file=deps_file) + print(f'pages = {" ".join(pages)}', file=deps_file) + print(f'autoindices = {" ".join(autoindices)}', file=deps_file) def main(arguments): extensions, out_dir = parse_arguments(arguments) repository = Repo(search_parent_directories=True) - top_dir = repository.working_dir - - source_files = find_sources(extensions, repository) + top_dir = path.relpath(repository.working_dir, path.curdir) - directories = compute_directories(source_files, top_dir) + directories = compute_directories(extensions, repository) with open('deps.mk', 'w') as deps: write_dependencies(deps, directories, top_dir, out_dir) diff --git a/repo/www/make-index.py b/repo/www/make-index.py new file mode 100755 index 0000000..07aa266 --- /dev/null +++ b/repo/www/make-index.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 + +from os import path +from subprocess import run +from sys import argv, exit + +from git import Repo + +from helpers import compute_directories + + +def parse_arguments(args): + if len(args) != 4: + exit(f'Usage: {argv[0]} EXTENSIONS FOLDER OUTPUT-DIR') + + return argv[1].split(), argv[2], argv[3] + + +def list_files(extensions, folder): + directories = compute_directories( + extensions, Repo(search_parent_directories=True) + ) + return directories[folder].subfolders, directories[folder].files + + +def generate_index_page(title, directories, files): + lines = (f'% {title}',) + tuple( + f'- [{d}/]({d}/index.html)' for d in directories + ) + tuple( + f'- [{f}]({f}.html)' for f in files + ) + mdown = '\n'.join(lines) + + return run( + ('pandoc', '-s'), text=True, check=True, capture_output=True, + input=mdown + ).stdout + + +def main(arguments): + extensions, folder, out_dir = parse_arguments(arguments) + + title = path.basename(folder) if folder else 'index' + + folders, files = list_files(extensions, folder) + + parsed_filenames = (path.splitext(f) for f in files) + names = tuple(name for name, _ in parsed_filenames) + + with open(path.join(out_dir, folder, 'index.html'), 'w') as index: + index.write(generate_index_page(title, folders, names)) + + +if __name__ == '__main__': + main(argv) |
