-
Notifications
You must be signed in to change notification settings - Fork 20
/
generate_contents.py
executable file
·125 lines (90 loc) · 2.76 KB
/
generate_contents.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
#!/usr/bin/env python3
"""
Converted a tab-indented input file of chapters > sections > subsections, etc
into a markdown hierarchy.
Usage:
- Populate a file "in.txt" like sample input below
- Run it
- Use redirection to write to an output file instead of the shell
Input:
# My Book Title
Introduction
Chapter 1
Section 1.1
Section 1.1.1
Section 1.2
Chapter 2
Section 2.1
Conclusion
Output:
# My Book Title
## Introduction
## Chapter 1
### Section 1.1
#### Section 1.1.1
### Section 1.2
## Chapter 2
### Section 2.1
## Conclusion
"""
import re
def load_file(filename):
"""Load contents of an input file."""
try:
with open(filename) as fp:
# no lstrip() because leading indentation is significant
text = fp.read().rstrip()
except FileNotFoundError as e:
exit(f'Error: Input file "{filename}" does not exist.')
if text == '':
exit(f'Error: Input file "{filename}" is blank.')
return text.split(sep='\n')
def parse_title(lines):
"""Parse optional book title."""
TITLE_PREFIX = '# '
book_title = None
if lines[0].startswith(TITLE_PREFIX):
book_title = lines.pop(0)[len(TITLE_PREFIX):].strip()
return book_title
def parse_body(lines):
"""Parse chapter titles, subtitles, etc and depth level."""
chapters = []
for chapter in lines:
depth = len(re.findall(r' {4}|\t', chapter))
title = chapter.strip()
if len(title) != 0:
chapters.append((title, depth))
return chapters
def parse(lines):
"""Parse input file."""
title = parse_title(lines)
chapters = parse_body(lines)
return title, chapters
def serialize_heading(title, depth):
"""Generate h1-h6 in markdown."""
hashes = '#' * depth
return f'{hashes} {title}'
def serialize_title(title):
"""Generate markdown for title."""
return serialize_heading(title, depth=1) if title is not None else ''
def serialize_chapters(chapters):
"""Generate markdown for chapters."""
markdown_chapters = []
for title, indent in chapters:
markdown_chapter = serialize_heading(title, depth=indent+2)
if indent == 0:
markdown_chapter = '\n' + markdown_chapter
markdown_chapters.append(markdown_chapter)
return markdown_chapters
def serialize(title, chapters):
"""Generate markdown components and concatenate."""
title_md = [serialize_title(title) + '\n']
chapters_md = serialize_chapters(chapters)
return '\n'.join(title_md + chapters_md).strip()
def main():
"""Convert tab tree to markdown."""
lines = load_file('in.txt')
output = serialize(*parse(lines))
print(output)
if __name__ == '__main__':
main()