]> Shamusworld >> Repos - ardour-manual-diverged/blob - build.py
2a8c8493530b119d41c0808ecdda7bf50d654665
[ardour-manual-diverged] / build.py
1 #!/usr/bin/python
2 #
3 # Script to take the master document and create something that build.rb wants.
4 # Eventually, this will replace build.rb
5 #
6 # Ultimately, we will write directly to the finished web site structure instead
7 # of creating this half-assed thing that we then rely on the other ruby script
8 # to handle. It works, but isn't optimal. :-P
9 #
10 # by James Hammons
11 # (C) 2017 Underground Software
12 #
13
14 import os
15 import re
16 import shutil
17
18 #
19 # Create an all lowercase filename without special characters and with spaces
20 # replaced with dashes.
21 #
22 def MakeFilename(s):
23         # This RE is shitty, but I can't think of a better one right now
24         fn = re.sub("[?!'&#:;_*()/\\,.]+", "", s)
25         fn = fn.lower()
26         fn = fn.replace(' ', '-')
27         return fn
28
29
30 # Preliminaries
31
32 buildDir = './_manual.munge/'
33
34 if os.access(buildDir, os.F_OK):
35         print('Removing stale manual data...')
36         shutil.rmtree(buildDir)
37
38 os.mkdir(buildDir, 0o774)
39
40 # Yeah, need to make a symlink in include/ too :-P
41 # [this will go away when the rewrite happens]
42 if (os.access('include/_manual', os.F_OK) == False):
43         os.symlink('../_manual/', 'include/_manual')
44
45
46 # Here we go!
47
48 master = open('master-doc.txt')
49
50 toc = open(buildDir + '00_toc.html', 'w')
51 toc.write('---\n' + 'title: Ardour Table of Contents\n' + '---\n\n')
52
53
54 roman = [ '0', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X',
55         'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX',
56         'XXI', 'XXII', 'XXIII', 'XXIV', 'XXV', 'XXVI', 'XXVII', 'XXVIII', 'XXIX', 'XXX' ]
57 level = 0
58 lastLevel = 0
59 lineCount = 0
60 levelNames = [None]*6
61 levelNums = [0]*6
62 writingToFile = False
63 # This is a shitty way of getting a filehandle...
64 htmlFile = open('master-doc.txt')
65 htmlFile.close()
66 lastFile = ''
67
68 firstLine = master.readline().rstrip('\r\n')
69
70 if firstLine == '<!-- exploded -->':
71         print('Parsing exploded file...\n')
72 elif firstLine == '<!-- imploded -->':
73         print('Parsing imploded file...\n')
74 else:
75         print('Parsing unknown type...\n')
76
77 for line in master:
78         lineCount = lineCount + 1
79
80         # Do any header parsing if needed...
81         if line.startswith('---'):
82
83                 # Close any open files that may have been opened from the last header...
84                 if writingToFile:
85                         htmlFile.close()
86                         writingToFile = False
87
88                 header = {}
89
90                 while (True):
91                         hdrLine = master.readline().rstrip('\r\n')
92                         lineCount = lineCount + 1
93
94                         # Break out of the loop if we hit the end of header marker
95                         if hdrLine.startswith('---'):
96                                 break
97
98                         # Parse out foo: bar pairs & put into header dictionary
99                         a = re.split(': ', hdrLine, 1)
100                         header[a[0]] = a[1]
101
102                 # Header has been parsed, now do something about it...
103                 lastLevel = level
104
105                 # Handle Part/Chapter/subchapter/section/subsection numbering
106                 if (header['part'] == 'part'):
107                         level = 0
108                         levelNums[2] = 0
109                 elif (header['part'] == 'chapter'):
110                         level = 1
111                         levelNums[2] = 0
112                 elif (header['part'] == 'subchapter'):
113                         level = 2
114                         levelNums[3] = 0
115                 elif (header['part'] == 'section'):
116                         level = 3
117                         levelNums[4] = 0
118                 elif (header['part'] == 'subsection'):
119                         level = 4
120
121                 levelNums[level] = levelNums[level] + 1;
122
123                 # This is totally unnecessary, but nice; besides which, you can capture
124                 # the output to a file to look at later if you like :-)
125                 for i in range(level):
126                         print('\t', end='')
127
128                 if (level == 0):
129                         print('\nPart ' + roman[levelNums[0]] + ': ', end='')
130                 elif (level == 1):
131                         print('\n\tChapter ' + str(levelNums[1]) + ': ', end='')
132
133                 print(header['title'])
134
135                 # Make a filename from the title...
136                 levelNames[level] = MakeFilename(header['title'])
137                 path = ''
138
139                 for i in range(level):
140                         path = path + str(levelNums[i]).zfill(2) + '_' + levelNames[i] + '/'
141
142                 path = path + str(levelNums[level]).zfill(2) + '_' + levelNames[level]
143
144                 # Append the appropriate footer to the last file, if the current file
145                 # is one level down from the previous...
146                 if ((level > 0) and (level > lastLevel)):
147                         nfile = open(buildDir + lastFile + '.html', 'a')
148                         nfile.write('\n{% children %}\n\n')
149                         nfile.close()
150
151                 # Handle TOC scriblings...
152                 if level == 0:
153                         toc.write('<h2>Part ' + roman[levelNums[level]] + ': ' + header['title'] + '</h2>\n');
154                 elif level == 1:
155                         toc.write('  <p id=chapter>Ch. ' + str(levelNums[level]) + ':&nbsp;&nbsp;<a href="/' + levelNames[0] + '/' + levelNames[1] + '/">' + header['title'] + '</a></p>\n')
156                 elif level == 2:
157                         toc.write('    <a id=subchapter href="/' + levelNames[0] + '/' + levelNames[1] + '/' + levelNames[2] + '/">' + header['title'] + '</a><br>\n')
158                 elif level == 3:
159                         toc.write('      <a id=subchapter href="/' + levelNames[0] + '/' + levelNames[1] + '/' + levelNames[2] + '/' + levelNames[3] + '/">' + header['title'] + '</a><br>\n')
160                 elif level == 4:
161                         toc.write('      <a id=subchapter href="/' + levelNames[0] + '/' + levelNames[1] + '/' + levelNames[2] + '/' + levelNames[3] + '/' + levelNames[4] + '/">' + header['title'] + '</a><br>\n')
162
163                 # Parts DO NOT have any content, they are ONLY an organizing construct!
164                 if (level == 0):
165                         os.mkdir(buildDir + path, 0o774)
166                         nfile = open(buildDir + path + '.html', 'w')
167                         nfile.write('---\n' + 'title: ' + header['title'] + '\n')
168
169                         if ('menu_title' in header):
170                                 nfile.write('menu_title: ' + header['menu_title'] + '\n')
171
172                         nfile.write('---\n\n')
173                         nfile.close()
174
175                 # Chapters, subchapters, sections & subsections all can have content.
176                 # But the basic fundamental organizing unit WRT content is still the
177                 # chapter.
178                 else:
179                         os.mkdir(buildDir + path, 0o774)
180
181                         if ('include' in header):
182                                 shutil.copy('include/' + header['include'], buildDir + path + '.html')
183                         else:
184                                 htmlFile = open(buildDir + path + '.html', 'w')
185                                 writingToFile = True
186                                 htmlFile.write('---\n' + 'title: ' + header['title'] + '\n')
187
188                                 if ('menu_title' in header):
189                                         htmlFile.write('menu_title: ' + header['menu_title'] + '\n')
190
191                                 if ('style' in header):
192                                         htmlFile.write('style: ' + header['style'] + '\n')
193
194                                 htmlFile.write('---\n\n')
195
196                 # Save filename for next header...
197                 lastFile = path
198
199         # No header, in that case, just dump the lines into the currently open file
200         else:
201                 if (writingToFile and (level > 0)):
202                         htmlFile.write(line)
203
204
205 master.close()
206 toc.close()
207
208 if writingToFile:
209         htmlFile.close()
210
211 print('\nProcessed ' + str(lineCount) + ' lines.')
212