forked from easybuilders/easybuild-docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsoftware-markdown-pages.py
132 lines (105 loc) · 5.4 KB
/
software-markdown-pages.py
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
122
123
124
125
126
127
128
129
130
131
132
import argparse
import json
import shutil
import sys
from collections import defaultdict
from pathlib import Path
MKDOCS_SEARCH_PRIORITY = """---
search:
boost: 0.5
---
"""
def generate_quick_links_line(chars, level, current=None):
"""
Generate links to index page for each character
:param characters: Initial characters to generate links for
"""
up = '/'.join(['..'] * level) or '.'
links = []
if level > 0:
links.append(f"[(all)]({up}/index.md)")
for char in chars:
if char == current:
links.append(f'*{char}*')
else:
links.append(f"[{char}]({up}/{char}/index.md)")
links_txt = ' - '.join(links)
return f"*(quick links: {links_txt})*\n\n"
def output_markdown(processed, output_base_path):
"""
Output markdown pages (index and per letter directories, each with an index and page per software)
:param processed: Processed data to output (dictionary - letter -> software -> list of versions)
:param output_base_path: Pathlib object for base path of output
"""
pkg_cnt = sum(len(v) for v in processed.values())
letters = sorted(processed.keys())
with open(output_base_path / 'index.md', 'w') as top_page:
top_page.write(MKDOCS_SEARCH_PRIORITY)
top_page.write("# List of supported software\n\n")
top_page.write(generate_quick_links_line(letters, 0))
top_page.write(f"EasyBuild supports {pkg_cnt} different software packages (incl. toolchains, bundles):\n\n")
for letter in processed:
top_page.write(f" * [{letter}]({letter}/index.md)\n")
letter_dir = output_base_path / letter
letter_dir.mkdir()
with open(letter_dir / 'index.md', 'w') as letter_page:
letter_page.write(MKDOCS_SEARCH_PRIORITY)
letter_page.write(f"# List of supported software ({letter})\n\n")
letter_page.write(generate_quick_links_line(letters, 1, current=letter) + "\n\n")
for software in processed[letter]:
top_page.write(f" * [{software}]({letter}/{software}.md)\n")
letter_page.write(f" * [{software}]({software}.md)\n")
versionsuffix = any(v['versionsuffix'] for v in processed[letter][software])
with open(letter_dir / f'{software}.md', 'w') as software_page:
software_page.write(MKDOCS_SEARCH_PRIORITY)
software_page.write(f"# {software}\n\n")
software_page.write(f"{processed[letter][software][0]['description']}\n\n")
software_page.write(f"*homepage*: <{processed[letter][software][0]['homepage']}>\n\n")
if versionsuffix:
software_page.write("version | versionsuffix | toolchain\n")
software_page.write("--------|---------------|----------\n")
else:
software_page.write("version | toolchain\n")
software_page.write("--------|----------\n")
for version in processed[letter][software]:
software_page.write(f"``{version['version']}`` | ")
if versionsuffix:
if version['versionsuffix']:
software_page.write(f"``{version['versionsuffix']}``")
software_page.write(" | ")
software_page.write(f"``{version['toolchain']}``\n")
software_page.write("\n\n" + generate_quick_links_line(letters, 1))
letter_page.write("\n\n" + generate_quick_links_line(letters, 1, current=letter))
top_page.write("\n\n" + generate_quick_links_line(letters, 0))
def generate_markdown_pages(jsonfile, output_base, delete_existing):
"""
Generate markdown
:param jsonfile: input file (json file)
:param output_base: base directory for output files
:param delete_existing: delete the output directory (if it exists)
"""
if jsonfile is None:
sys.stderr.write("ERROR: No input JSON file specified, it is required!\n")
sys.exit(1)
with open(jsonfile) as f:
data = json.load(f)
processed = defaultdict(lambda: defaultdict(list))
for software in data:
initial = software['name'][0].lower()
if initial.isnumeric():
initial = '0'
processed[initial][software['name']].append(software)
output_base_path = Path(output_base)
if delete_existing and output_base_path.exists() and output_base_path.is_dir():
shutil.rmtree(output_base_path)
output_base_path.mkdir(parents=True)
output_markdown(processed, output_base_path)
if __name__ == "__main__":
parser = argparse.ArgumentParser(prog='Software Markdown Pages',
description='Generate Markdown pages of software from JSON file')
parser.add_argument('-j', '--jsonfile', default=None, help='Input JSON file')
parser.add_argument('-o', '--output-base', default='output', help='Base directory for output files')
parser.add_argument('--delete-existing-output', action='store_true',
help='Delete output base directory (if it exists)')
args = parser.parse_args()
generate_markdown_pages(args.jsonfile, args.output_base, args.delete_existing_output)