summaryrefslogtreecommitdiff
path: root/repo/www/generate-index.py
blob: c51bf98c83dd07bc2097101a771991176f8bdf0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env python3

from argparse import ArgumentParser
from itertools import chain
import json
from pathlib import Path
from subprocess import run

from git import Repo

from helpers import deserialize_directories


def parse_arguments():
    parser = ArgumentParser()
    parser.add_argument(
        '--template', help='Pandoc template for HTML output.'
    )
    parser.add_argument(
        '--site-title', help='Prefix to add to <title>.'
    )
    parser.add_argument(
        'site_tree', help='JSON file describing the page tree.'
    )
    parser.add_argument(
        'target', help='Subfolder to generate an index for.'
    )
    parser.add_argument(
        'output', help='Path to the output file.'
    )
    return parser.parse_args()


def list_files(tree_file, folder):
    with open(tree_file) as tree:
        directories = deserialize_directories(json.load(tree))
    return directories[folder].subfolders, directories[folder].files


def has_title(markdown):
    pandoc = run(
        ('pandoc', '-t', 'json'), input=markdown,
        check=True, text=True, capture_output=True
    )
    ast = json.loads(pandoc.stdout)
    return 'title' in ast['meta']


def format_readme_index(readme, title, items):
    blocks = [
        readme,
        f'# {title}',
        items
    ]

    if not has_title(readme):
        blocks.insert(0, '% README')

    return '\n\n'.join(blocks)


def format_plain_index(title, items):
    return '\n'.join((f'% {title}', items))


def list_pages(files):
    readme = None
    pages = []

    for f in files:
        page = Path(f).stem

        if page == 'README':
            readme = f
        else:
            pages.append(page)

    return pages, readme


def format_index(target, directories, files):
    pages, readme = list_pages(files)

    dir_list = (
        f'- [{d}/]({d}/index.html)' for d in directories
    )
    page_list = (
        f'- [{p}]({p}.html)' for p in pages
    )
    items = '\n'.join(chain(dir_list, page_list))

    title = f'Index for {target}' if target else 'Index'

    if readme is None:
        return format_plain_index(title, items)

    repo_top = Repo(search_parent_directories=True).working_dir
    intro = Path(repo_top, target, readme).read_text()
    return format_readme_index(intro, title, items)


def convert_page(content, output, site_title, template):
    pandoc = (
        'pandoc', '-s', '--lua-filter', 'convert-internal-links.lua',
        '--template', template, '-o', output
    )
    if site_title is not None:
        pandoc += ('-T', site_title)

    run(pandoc, input=content, check=True, text=True)


def main(arguments):
    folders, files = list_files(arguments.site_tree, arguments.target)
    index_page = format_index(arguments.target, folders, files)
    convert_page(index_page, arguments.output, arguments.site_title,
                 arguments.template)


if __name__ == '__main__':
    main(parse_arguments())