Table of Contents \n', 1)
return content
+
# Preliminaries
# We have command line arguments now, so deal with them
@@ -386,54 +418,65 @@ parser = argparse.ArgumentParser(description='A build script for the Ardour Manu
parser.add_argument('-v', '--verbose', action='store_true', help='Display the high-level structure of the manual')
parser.add_argument('-q', '--quiet', action='store_true', help='Suppress all output (overrides -v)')
parser.add_argument('-d', '--devmode', action='store_true', help='Add content to pages to help developers debug them')
+parser.add_argument('-p', '--pdf', action='store_true', help='Automatically generate PDF from content')
args = parser.parse_args()
verbose = args.verbose
-quiet = args.quiet
+noisy = not args.quiet
devmode = args.devmode
+pdf = args.pdf
-if quiet:
+# --quiet overrides --verbose, so tell it to shut up if user did both
+if not noisy:
verbose = False
level = 0
fileCount = 0
-levelNums = [0]*6
+levelNums = [0] * 5
lastFile = ''
page = ''
onepage = ''
+pdfpage = ''
toc = ''
pageNumber = 0
-siteDir = './website/'
-
-if not quiet and devmode:
+if noisy and devmode:
print('Devmode active: scribbling extra junk to the manual...')
-if os.access(siteDir, os.F_OK):
- if not quiet:
+if os.access(global_site_dir, os.F_OK):
+ if noisy:
print('Removing stale HTML data...')
- shutil.rmtree(siteDir)
-
-shutil.copytree('./source', siteDir)
+ shutil.rmtree(global_site_dir)
+shutil.copytree('./source', global_site_dir)
# Read the template, and fix the stuff that's fixed for all pages
-temp = open('page-template.txt')
+temp = open(global_screen_template)
template = temp.read()
temp.close()
+template = template.replace('{{page.bootstrap_path}}', global_bootstrap_path)
+template = template.replace('{{page.page_title}}', global_page_title)
+if pdf:
+ template = template.replace('{{page.page_pdflink}}', global_pdflink)
+else:
+ template = template.replace('{{page.page_pdflink}}', '')
-template = template.replace('{{page.bootstrap_path}}', '/bootstrap-3.3.7')
-template = template.replace('{{page.page_title}}', 'The Ardour Manual')
-# Same as above, but for the One-page version
-temp = open('onepage-template.txt')
+# Same as above, but for the "One-Page" version
+temp = open(global_onepage_template)
onepage = temp.read()
temp.close()
+onepage = onepage.replace('{{page.bootstrap_path}}', global_bootstrap_path)
+onepage = onepage.replace('{{page.page_title}}', global_page_title)
-onepage = onepage.replace('{{page.bootstrap_path}}', '/bootstrap-3.3.7')
-onepage = onepage.replace('{{page.page_title}}', 'The Ardour Manual')
+if pdf:
+ # Same as above, but for the PDF version
+ temp = open(global_pdf_template)
+ pdfpage = temp.read()
+ temp.close()
+ pdfpage = pdfpage.replace('{{page.page_title}}', global_page_title)
-# Parse out the master docuemnt's structure into a dictionary list
+# Parse out the master document's structure into a dictionary list
fileStruct = GetFileStructure()
# Build a quasi-tree structure listing children at level + 1 for each node
@@ -443,12 +486,12 @@ nodeChildren = FindChildren(fileStruct)
links = FindInternalLinks(fileStruct)
oplinks = FindInternalAnchors(fileStruct)
-if not quiet:
+if noisy:
print('Found ' + str(len(links)) + ' internal link target', end='')
print('.') if len(links) == 1 else print('s.')
-if not quiet:
- master = open('master-doc.txt')
+if noisy:
+ master = open(global_master_doc)
firstLine = master.readline().rstrip('\r\n')
master.close()
@@ -470,14 +513,8 @@ for header in fileStruct:
level = header['level']
# Handle Part/Chapter/subchapter/section/subsection numbering
- if level == 0:
+ if level < 2:
levelNums[2] = 0
- elif level == 1:
- levelNums[2] = 0
- elif level == 2:
- levelNums[3] = 0
- elif level == 3:
- levelNums[4] = 0
levelNums[level] = levelNums[level] + 1;
@@ -494,31 +531,17 @@ for header in fileStruct:
print(header['title'])
- # Handle TOC scriblings and one-page titles...
- opl = ''
- if 'link' in header:
- opl = ' id="' + header['link'] + '"'
- else:
- opl = ' id="' + header['filename'] + '"'
-
+ # Handle TOC scriblings...
if level == 0:
toc = toc + 'Part ' + num2roman(levelNums[level]) + ': ' + header['title'] + ' \n';
- oph = 'Part ' + num2roman(levelNums[level]) + ': ' + header['title'] + ' \n';
elif level == 1:
- toc = toc + ' Ch. ' + str(levelNums[level]) + ': ' + header['title'] + '
\n'
- oph = 'Chapter ' + str(levelNums[level]) + ': ' + header['title'] + ' \n';
+ toc = toc + '\tCh. ' + str(levelNums[level]) + ': ' + header['title'] + '
\n'
elif level == 2:
- toc = toc + ' ' + header['title'] + '
\n'
- oph = 'Subchapter ' + str(levelNums[level]) + ': ' + header['title'] + ' \n';
+ toc = toc + '\t\t' + header['title'] + '
\n'
elif level == 3:
- toc = toc + ' ' + header['title'] + '
\n'
- oph = 'Section ' + str(levelNums[level]) + ': ' + header['title'] + ' \n';
+ toc = toc + '' + header['title'] + '
\n'
elif level == 4:
- toc = toc + ' ' + header['title'] + '
\n'
- oph = 'Subsection ' + str(levelNums[level]) + ': ' + header['title'] + ' \n';
-
-
-
+ toc = toc + '' + header['title'] + '
\n'
# Make the 'this thing contains...' stuff
if HaveChildren(fileStruct, pageNumber):
@@ -560,10 +583,11 @@ for header in fileStruct:
# but the basic fundamental organizing unit WRT content is still the
# chapter.
githubedit = ''
+
if level > 0:
if 'include' in header:
srcFile = open('include/' + header['include'])
- githubedit = ' '
+ githubedit = ' '
content = srcFile.read()
srcFile.close()
@@ -582,25 +606,35 @@ for header in fileStruct:
# Add header information to the page if in dev mode
if devmode:
devnote =''
+
if 'filename' in header:
devnote = devnote + 'filename: ' + header['filename'] + ' '
+
if 'include' in header:
devnote = devnote + 'include: ' + header['include'] + ' '
+
if 'link' in header:
devnote = devnote + 'link: ' + header['link'] + ' '
+
content = devnote + ' ' + content
- # ----- One page version -----
+ # ----- One page and PDF version -----
# Fix up any internal links
opcontent = FixInternalLinks(oplinks, content, header['title'])
+ opcontent = reheader(opcontent, 2)
- # Create the link sidebar
- opsidebar = BuildOnePageSidebar(fileStruct)
+ # Create "one page" header
+ oph = '\n';
# Set up the actual page from the template
- onepage = onepage.replace('{% tree %}', opsidebar)
- onepage = onepage.replace('{{ content }}', oph + '\n' + opcontent + '{{ content }}')
+ onepage = onepage.replace('{{ content }}', oph + '\n' + opcontent + '\n{{ content }}')
+
+ if pdf:
+ if not 'pdf-exclude' in header:
+ pdfpage = pdfpage.replace('{{ content }}', oph + '\n' + opcontent + '\n{{ content }}')
+ else:
+ pdfpage = pdfpage.replace('{{ content }}', oph + '\n' + 'Please refer to the online manual .\n{{ content }}')
# ----- Normal version -----
@@ -624,10 +658,10 @@ for header in fileStruct:
# Create the directory for the index.html file to go into (we use makedirs,
# because we have to in order to accomodate the 'uri' keyword)
- os.makedirs(siteDir + header['filename'], 0o775, exist_ok=True)
+ os.makedirs(global_site_dir + header['filename'], 0o775, exist_ok=True)
# Finally, write the file!
- destFile = open(siteDir + header['filename'] + '/index.html', 'w')
+ destFile = open(global_site_dir + header['filename'] + '/index.html', 'w')
destFile.write(page)
destFile.close()
@@ -646,16 +680,45 @@ page = page.replace('{% prevnext %}', '')
page = page.replace('{% githubedit %}', '')
page = page.replace('{% breadcrumbs %}', '')
-os.mkdir(siteDir + 'toc', 0o775)
-tocFile = open(siteDir + 'toc/index.html', 'w')
+os.mkdir(global_site_dir + 'toc', 0o775)
+tocFile = open(global_site_dir + 'toc/index.html', 'w')
tocFile.write(page)
tocFile.close()
# Create the one-page version of the documentation
-onepageFile = open(siteDir + 'ardourmanual.html', 'w')
+onepageFile = open(global_site_dir + 'ardourmanual.html', 'w')
+opsidebar = BuildOnePageSidebar(fileStruct) # create the link sidebar
+onepage = onepage.replace('{% tree %}', opsidebar)
+onepage = onepage.replace('{{ content }}', '') # cleans up the last spaceholder
onepageFile.write(onepage)
onepageFile.close()
-
-if not quiet:
+if pdf:
+ if noisy:
+ print('Generating the PDF...')
+ import logging
+ logger = logging.getLogger('weasyprint')
+ logger.addHandler(logging.StreamHandler())
+
+ # Create the PDF version of the documentation
+ pdfpage = pdfpage.replace('{% tree %}', opsidebar) # create the TOC
+ pdfpage = pdfpage.replace('{{ content }}', '') # cleans up the last spaceholder
+ pdfpage = pdfpage.replace('{{ today }}', global_today)
+ pdfpage = pdfpage.replace('src="/images/', 'src="images/') # makes images links relative
+ pdfpage = pdfpage.replace('url(\'/images/', 'url(\'images/') # CSS images links relative
+ # Write it to disk (optional, can be removed)
+ pdfpageFile = open(global_site_dir + 'pdf.html', 'w')
+ pdfpageFile.write(pdfpage)
+ pdfpageFile.close()
+
+ # Generating the actual PDF with weasyprint (https://weasyprint.org/)
+ from weasyprint import HTML
+ from weasyprint.fonts import FontConfiguration
+
+ html_font_config = FontConfiguration()
+ doc = HTML(string = pdfpage, base_url = global_site_dir)
+ doc.write_pdf(global_site_dir + 'manual.pdf', font_config = html_font_config)
+
+if noisy:
print('Processed ' + str(fileCount) + ' files.')
+