/
nbtoc.py
executable file
·126 lines (101 loc) · 3.86 KB
/
nbtoc.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
#!/usr/bin/env python
# Create table of contents for given notebook(s)
"""
usage:
python nbtoc.py A.ipynb B.ipynb C.ipynb
"""
import io, os, sys, types, re
import nbformat
import argparse
def get_text_contents(notebook):
with io.open(notebook, 'r', encoding='utf-8') as f:
nb = nbformat.read(f, as_version=4)
contents = ""
for cell in nb.cells:
if cell.cell_type == 'markdown':
contents += "".join(cell.source) + "\n\n"
# print("Contents of", notebook, ": ", repr(contents[:100]))
return contents
def get_title(notebook):
"""Return the title from a notebook file"""
contents = get_text_contents(notebook)
match = re.search(r'^# (.*)', contents, re.MULTILINE)
title = match.group(1).replace(r'\n', '')
# print("Title", title.encode('utf-8'))
return title
def notebook_toc_entry(notebook_name, prefix, path=None):
# notebook_path = import_notebooks.find_notebook(notebook_name, path)
notebook_path = notebook_name
notebook_title = get_title(notebook_path)
notebook_base = os.path.basename(notebook_path)
return prefix + " [" + notebook_title + "](" + notebook_base + ")\n"
def notebook_toc(public_chapters, appendices):
title = "# Generating Software Tests"
chapter_toc = "## Table of Contents\n\n"
counter = 1
for notebook in public_chapters:
notebook_title = get_title(notebook)
if notebook_title.startswith("Part "):
# chapter_toc += "\n### " + notebook_title + "\n\n"
chapter_toc += "\n" + notebook_toc_entry(notebook, "###") + "\n"
else:
chapter_toc += notebook_toc_entry(notebook, "*") # repr(counter) + ".")
counter += 1
appendix_toc = "### Appendices\n\n"
for notebook in appendices:
appendix_toc += notebook_toc_entry(notebook, "*")
sitemap = r"""## Sitemap
This sitemap shows possible paths through the book chapters. An arrow $A \rightarrow B$ means that chapter $A$ is a prerequisite for chapter $B$."""
sitemap_code_1 = "import IPython"
sitemap_code_2 = "IPython.display.SVG(filename='00_Sitemap.svg')"
toc_notebook = nbformat.v4.new_notebook(
cells=[
nbformat.v4.new_markdown_cell(source=title),
nbformat.v4.new_markdown_cell(source=sitemap),
nbformat.v4.new_code_cell(source=sitemap_code_1),
nbformat.v4.new_code_cell(source=sitemap_code_2),
nbformat.v4.new_markdown_cell(source=chapter_toc),
nbformat.v4.new_markdown_cell(source=appendix_toc),
])
# Get along with TOC extension
toc_notebook.metadata['toc'] = {
"base_numbering": 1,
"nav_menu": {},
"number_sections": False,
"sideBar": False,
"skip_h1_title": False,
"title_cell": "",
"title_sidebar": "Contents",
"toc_cell": False,
"toc_position": {},
"toc_section_display": False,
"toc_window_display": False
}
# Add general metadata
toc_notebook.metadata["kernelspec"] = {
"display_name": "Python 3",
"language": "python",
"name": "python3"
}
toc_notebook.metadata["language_info"] = {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
return toc_notebook
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--chapters", help="List of public chapters")
parser.add_argument("--appendices", help="List of appendices")
args = parser.parse_args()
public_chapters = args.chapters.split()
appendices = args.appendices.split()
toc_notebook = notebook_toc(public_chapters, appendices)
sys.stdout.buffer.write(nbformat.writes(toc_notebook).encode("utf-8"))