This repository has been archived by the owner on Apr 13, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build_codex.py
executable file
·115 lines (96 loc) · 3.67 KB
/
build_codex.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
import argparse
import markdown
from operator import attrgetter
import os
"""
Create a static HTML site from a directory of text files, annotated
with Markdown.
Usage:
build_codex.py source_directory target_directory
"""
class Page:
def __init__(self, name, path):
self.name = name
self.path = path
def get_file_path(self, root_path=""):
return os.path.join(root_path, self.get_dir_path(), self.name)
def get_dir_path(self):
if self.path:
return apply(os.path.join, self.path)
return ""
def get_relative_path(self, target):
"""Return a file path from the current page to the target path"""
sp = self.path
tp = target.path
i = len(sp) - 1
o = ""
# Traverse down
while i >= 0 and not (len(tp) > i and tp[i] == sp[i]):
o = os.path.join("..", o)
i -= 1
i += 1
# Traverse up
while i < len(tp):
o = os.path.join(o, tp[i])
i += 1
return os.path.join(o, target.name)
def load_html(page, root_path):
"""Load the page text and convert the markdown to HTML"""
with open(page.get_file_path(root_path), "rb") as f:
return markdown.markdown(f.read(), ['def_list'])
def create_html_file(page, content_html, template, target_root):
"""Create an output HTML file for this page"""
html = template.replace("{{CONTENT}}", content_html) \
.replace("{{TITLE}}", page.name)
output_dir = os.path.join(target_root, page.get_dir_path())
if not os.path.exists(output_dir):
os.makedirs(output_dir)
output_path = os.path.join(target_root, page.get_file_path()) + ".htm"
with open(output_path, "wb") as f:
f.write(html)
def build_nav(page_map, current_page):
"""Build navigation from the current page to all pages in the page map"""
o = "<ul>"
for dir, pages in sorted(page_map.items()):
o += '<li>%s</a><ul>\n' % dir
for page in pages:
link = current_page.get_relative_path(page) + ".htm"
o += '<li><a href="%s">%s</a></li>\n' % (link, page.name)
o += ' </ul>\n'
o += '</li>\n'
return o + "</ul>"
def parse_args():
parser = argparse.ArgumentParser(description='Create a codex site')
parser.add_argument('source', help='location of source text files')
parser.add_argument('target', help='destination of generated html files')
args = parser.parse_args()
return args
def create_site(source_root, target_root):
page_map = {}
# Find pages in the source_root
top_dirs = os.listdir(source_root)
top_dirs.sort()
for f in top_dirs:
path = os.path.join(source_root, f)
if os.path.isdir(path):
page_map[f] = []
for g in os.listdir(path):
if os.path.isfile(os.path.join(path, g)):
page_map[f].append(Page(g, [f]))
page_map[f] = sorted(page_map[f], key=attrgetter('name'))
template = open("template.htm").read()
# Product output files
for dir, pages in page_map.items():
for page in pages:
nav = build_nav(page_map, page)
page_template = template.replace("{{NAV}}", nav)
content_html = load_html(page, source_root)
create_html_file(page, content_html, page_template, target_root)
# Build index page (won't appear in nav)
index_page = Page("index", [])
nav = build_nav(page_map, index_page)
page_template = template.replace("{{NAV}}", nav)
create_html_file(index_page, "", page_template, target_root)
if __name__ == "__main__":
args = parse_args()
create_site(args.source, args.target)