--- /dev/null
+#!/usr/bin/python
+#
+# Script to take the master document and create something that build.rb wants.
+# Eventually, this will replace build.rb
+#
+# Ultimately, we will write directly to the finished web site structure instead
+# of creating this half-assed thing that we then rely on the other ruby script
+# to handle.
+#
+# by James Hammons
+#
+
+import os
+import re
+import shutil
+
+#
+# Create an all lowercase filename without special characters and with spaces
+# replaced with dashes.
+#
+def MakeFilename(s):
+ # This RE is shitty, but I can't think of a better one right now
+ fn = re.sub("[?!'&#:;_*()/\\,.]+", "", s)
+ fn = fn.lower()
+ fn = fn.replace(' ', '-')
+ return fn
+
+
+# Preliminaries
+
+buildDir = './_manual.munge/'
+
+if os.access(buildDir, os.F_OK):
+ print('Removing stale manual data...')
+ shutil.rmtree(buildDir)
+
+os.mkdir(buildDir, 0o774)
+
+# Yeah, need to make a symlink in include/ too :-P
+# [this will go away when the rewrite happens]
+if (os.access('include/_manual', os.F_OK) == False):
+ os.symlink('../_manual/', 'include/_manual')
+
+
+# Here we go!
+
+master = open('master-doc.txt')
+
+toc = open(buildDir + '00_toc.html', 'w')
+toc.write('---\n' + 'title: Ardour Table of Contents\n' + '---\n\n')
+
+
+roman = [ '0', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X',
+ 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX',
+ 'XXI', 'XXII', 'XXIII', 'XXIV', 'XXV', 'XXVI', 'XXVII', 'XXVIII', 'XXIX', 'XXX' ]
+level = 0
+lastLevel = 0
+lineCount = 0
+levelNames = [None]*6
+levelNums = [0]*6
+writingToFile = False
+# This is a shitty way of getting a filehandle...
+htmlFile = open('master-doc.txt')
+htmlFile.close()
+lastFile = ''
+
+firstLine = master.readline().rstrip('\r\n')
+
+if firstLine == '<!-- exploded -->':
+ print('Parsing exploded file...\n')
+elif firstLine == '<!-- imploded -->':
+ print('Parsing imploded file...\n')
+else:
+ print('Parsing unknown type...\n')
+
+for line in master:
+ lineCount = lineCount + 1
+
+ # Do any header parsing if needed...
+ if line.startswith('---'):
+
+ # Close any open files that may have been opened from the last header...
+ if writingToFile:
+ htmlFile.close()
+ writingToFile = False
+
+ header = {}
+
+ while (True):
+ hdrLine = master.readline().rstrip('\r\n')
+ lineCount = lineCount + 1
+
+ # Break out of the loop if we hit the end of header marker
+ if hdrLine.startswith('---'):
+ break
+
+ # Parse out foo: bar pairs & put into header dictionary
+ a = re.split(': ', hdrLine, 1)
+ header[a[0]] = a[1]
+
+ # Header has been parsed, now do something about it...
+ lastLevel = level
+
+ # Handle Part/Chapter/subchapter/section/subsection numbering
+ if (header['part'] == 'part'):
+ level = 0
+ levelNums[2] = 0
+ elif (header['part'] == 'chapter'):
+ level = 1
+ levelNums[2] = 0
+ elif (header['part'] == 'subchapter'):
+ level = 2
+ levelNums[3] = 0
+ elif (header['part'] == 'section'):
+ level = 3
+ levelNums[4] = 0
+ elif (header['part'] == 'subsection'):
+ level = 4
+
+ levelNums[level] = levelNums[level] + 1;
+
+ # This is totally unnecessary, but nice; besides which, you can capture
+ # the output to a file to look at later if you like :-)
+ for i in range(level):
+ print('\t', end='')
+
+ if (level == 0):
+ print('\nPart ' + roman[levelNums[0]] + ': ', end='')
+ elif (level == 1):
+ print('\n\tChapter ' + str(levelNums[1]) + ': ', end='')
+
+ print(header['title'])
+
+ # Make a filename from the title...
+ levelNames[level] = MakeFilename(header['title'])
+
+ path = ''
+
+ for i in range(level):
+ path = path + str(levelNums[i]).zfill(2) + '_' + levelNames[i] + '/'
+
+ path = path + str(levelNums[level]).zfill(2) + '_' + levelNames[level]
+
+ # Append the appropriate footer, if the current file is one level
+ # down from the previous...
+ if ((level > 0) and (level > lastLevel)):
+ nfile = open(buildDir + lastFile + '.html', 'a')
+ nfile.write('\n{% children %}\n\n')
+ nfile.close()
+
+ # Parts DO NOT have any content, they are ONLY an organizing construct!
+ if (level == 0):
+ toc.write('<h2>Part ' + roman[levelNums[level]] + ': ' + header['title'] + '</h2>\n');
+
+ os.mkdir(buildDir + path, 0o774)
+ nfile = open(buildDir + path + '.html', 'w')
+ nfile.write('---\n' + 'title: ' + header['title'] + '\n')
+
+ if ('menu_title' in header):
+ nfile.write('menu_title: ' + header['menu_title'] + '\n')
+
+ nfile.write('---\n' + '\n{% children %}\n\n')
+ nfile.close()
+
+ # Chapters, subchapters, sections & subsections all can have content.
+ # But the basic fundamental organizing unit WRT content is still the
+ # chapter.
+ elif (level == 1):
+ toc.write(' <p id=chapter>Ch. ' + str(levelNums[level]) + ': <a href="/' + levelNames[0] + '/' + levelNames[1] + '/">' + header['title'] + '</a></p>\n')
+
+ os.mkdir(buildDir + path, 0o774)
+
+ if ('include' in header):
+ shutil.copy('include/' + header['include'], buildDir + path + '.html')
+ else:
+ htmlFile = open(buildDir + path + '.html', 'w')
+ writingToFile = True
+ htmlFile.write('---\n' + 'title: ' + header['title'] + '\n')
+
+ if ('menu_title' in header):
+ htmlFile.write('menu_title: ' + header['menu_title'] + '\n')
+
+ if ('style' in header):
+ htmlFile.write('style: ' + header['style'] + '\n')
+
+ htmlFile.write('---\n\n')
+
+ elif (level == 2):
+ toc.write(' <a id=subchapter href="/' + levelNames[0] + '/' + levelNames[1] + '/' + levelNames[2] + '/">' + header['title'] + '</a><br>\n')
+
+ os.mkdir(buildDir + path, 0o774)
+
+ if ('include' in header):
+ shutil.copy('include/' + header['include'], buildDir + path + '.html')
+ else:
+ htmlFile = open(buildDir + path + '.html', 'w')
+ writingToFile = True
+ htmlFile.write('---\n' + 'title: ' + header['title'] + '\n')
+
+ if ('menu_title' in header):
+ htmlFile.write('menu_title: ' + header['menu_title'] + '\n')
+
+ if ('style' in header):
+ htmlFile.write('style: ' + header['style'] + '\n')
+
+ htmlFile.write('---\n\n')
+
+ elif (level == 3):
+ toc.write(' <a id=subchapter href="/' + levelNames[0] + '/' + levelNames[1] + '/' + levelNames[2] + '/' + levelNames[3] + '/">' + header['title'] + '</a><br>\n')
+
+ os.mkdir(buildDir + path, 0o774)
+
+ if ('include' in header):
+ shutil.copy('include/' + header['include'], buildDir + path + '.html')
+ else:
+ htmlFile = open(buildDir + path + '.html', 'w')
+ writingToFile = True
+ htmlFile.write('---\n' + 'title: ' + header['title'] + '\n')
+
+ if ('menu_title' in header):
+ htmlFile.write('menu_title: ' + header['menu_title'] + '\n')
+
+ if ('style' in header):
+ htmlFile.write('style: ' + header['style'] + '\n')
+
+ htmlFile.write('---\n\n')
+
+ elif (level == 4):
+ toc.write(' <a id=subchapter href="/' + levelNames[0] + '/' + levelNames[1] + '/' + levelNames[2] + '/' + levelNames[3] + '/' + levelNames[4] + '/">' + header['title'] + '</a><br>\n')
+
+ os.mkdir(buildDir + path, 0o774)
+
+ if ('include' in header):
+ shutil.copy('include/' + header['include'], buildDir + path + '.html')
+ else:
+ htmlFile = open(buildDir + path + '.html', 'w')
+ writingToFile = True
+ htmlFile.write('---\n' + 'title: ' + header['title'] + '\n')
+
+ if ('menu_title' in header):
+ htmlFile.write('menu_title: ' + header['menu_title'] + '\n')
+
+ if ('style' in header):
+ htmlFile.write('style: ' + header['style'] + '\n')
+
+ htmlFile.write('---\n\n')
+
+ # Save filename for next header...
+ lastFile = path
+
+ # No header, in that case, just dump the lines into the currently open file
+ else:
+ if (writingToFile and (level > 0)):
+ htmlFile.write(line)
+
+
+master.close()
+toc.close()
+
+if writingToFile:
+ htmlFile.close()
+
+print('\nProcessed ' + str(lineCount) + ' lines.')
+
+++ /dev/null
-//
-// Program to massage the master doc file to spit out a bunch of little files
-// for the Ruby build script...
-//
-// by James Hammons
-// (C) 2016 Underground Software
-//
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h> // For mkdir()
-#include <sys/types.h>
-
-
-// Global variables (ZOMG YOU HIDEOUS BASTARD!!)
-char buffer[1024000], keyword[1024], token[1024];
-char title[1024], shortTitle[1024], inclFile[1024], style[1024];
-int level = 0, lastLevel = -1;
-int lineCount = 0, startLine, sectionLineCount;
-int part = 0, chapter = 0, subchapter = 0;
-bool first = true, nomove = false;
-FILE * newFile = NULL;
-char level1File[1024], level2File[1024], level3File[1024], temp[1024], temp2[1024];
-char partFN[1024], chapterFN[1024], scLink[4096];
-
-
-void MakeFilename(char * fn)
-{
- int l = strlen(fn);
-
- for(int i=0; i<l; i++)
- {
- if (fn[i] == ' ')
- fn[i] = '-';
- else if (fn[i] >= 'A' && fn[i] <= 'Z')
- fn[i] |= 0x20;
- else if (fn[i] >= 'a' && fn[i] <= 'z')
- ;
- else if (fn[i] >= '0' && fn[i] <= '9')
- ;
- else
- fn[i] = '_';
- }
-}
-
-
-//
-// There's probably posix function to do this, if you find it, feel free to
-// nuke this crap
-//
-void CopyFile(char * from, char * to)
-{
- FILE * fromFile = fopen(from, "r");
-
- if (fromFile == NULL)
- {
- printf("\n\nCould not open file '%s' for reading! Aborting!!\n", from);
- exit(1);
- }
-
- FILE * toFile = fopen(to, "w");
-
- if (toFile == NULL)
- {
- printf("\n\nCould not open file '%s' for writing! Aborting!!\n", to);
- exit(1);
- }
-
- fseek(fromFile, 0, SEEK_END);
- long length = ftell(fromFile);
- rewind(fromFile);
-
- for(long i=0; i<length; i++)
- fputc(fgetc(fromFile), toFile);
-
- fclose(toFile);
- fclose(fromFile);
-}
-
-
-bool ParseHeader(FILE * file)
-{
- while (true)
- {
- // If we hit the EOF before finishing, something went horribly wrong
- if (feof(file))
- break;
-
- fgets(buffer, 1023999, file);
- lineCount++;
-
- // If we're seeing the end of header sentinel, return; we're done.
- if (strncmp(buffer, "---", 3) == 0)
- return true;
-
- sscanf(buffer, "%[^:]: %[^\n]", keyword, token);
-
- if (strcmp(keyword, "title") == 0)
- {
- strcpy(title, token);
- }
- else if (strcmp(keyword, "part") == 0)
- {
- lastLevel = level;
- int len = strlen(token);
-
- if (len == 4)
- level = 0, part++;
- else if (len == 7)
- level = 1, chapter++, subchapter = 0;
- else if (len == 10)
- level = 2, subchapter++;
- else
- level = -1; // Something went wrong
- }
- else if (strcmp(keyword, "include") == 0)
- {
- strcpy(inclFile, token);
- }
- else if (strcmp(keyword, "menu_title") == 0)
- {
- strcpy(shortTitle, token);
- }
- else if (strcmp(keyword, "style") == 0)
- {
- strcpy(style, token);
- }
- else if (strcmp(keyword, "exclude") == 0)
- {
- // Don't care about the token, just the keyword
- nomove = true;
- }
- else
- printf("Unknown keyword '%s' (token: %s)\n", keyword, token);
- }
-
- // If we end up here, something went horribly wrong...
- return false;
-}
-
-
-int main(int argc, char * argv[])
-{
- char roman[21][10] = { "0", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX" };
-
- FILE * master = fopen("master-doc.txt", "r");
-
- if (master == NULL)
- {
- printf("Could not open master doc (master-doc.txt) file!\n");
- return -1;
- }
-
- FILE * toc = fopen("_manual.munge/00_toc.html", "w");
-
- if (toc == NULL)
- {
- printf("Could not open TOC file!\n");
- fclose(master);
- return -1;
- }
-
- fprintf(toc, "---\n");
- fprintf(toc, "title: Ardour Table of Contents\n");
- fprintf(toc, "---\n\n");
-
- while (!feof(master))
- {
- fgets(buffer, 1023999, master);
- lineCount++;
-
- // Look for start of file marker
- if (strncmp(buffer, "---", 3) == 0)
- {
- if (first)
- first = false;
- else
- {
- sectionLineCount = lineCount - startLine;
- printf(" (%d lines)\n", sectionLineCount);
- }
-
- // Reset the "short" title, include file & sytle
- shortTitle[0] = 0;
- inclFile[0] = 0;
- style[0] = 0;
- nomove = false;
-
- if (!ParseHeader(master))
- {
- printf("Something went horribly wrong with the header parsing! Aborting!\n");
- break;
- }
-
- // We hit the end of our keyword block, now do something
- // about it... :-P
- if (level == 0)
- printf("\nPart %s: ", roman[part]);
- else if (level == 1)
- printf("\n\tCh. %d: ", chapter);
- else if (level == 2)
- printf("\t\t");
-
- printf("%s", title);
-
- if (strlen(inclFile) > 0)
- printf(" [%s]", inclFile);
-
- startLine = lineCount;
-
- // Add appropriate suffix chapter content if needed
- if ((lastLevel == 1) && (level == 2))
- {
- if (newFile != NULL)
- {
- fprintf(newFile, "\n{%% children %%}\n\n");
- }
- else
- {
- // If it didn't stream, it was a included file, so append to
- // it directly...
- sprintf(temp2, "%s.html", level2File);
- FILE * tfp = fopen(temp2, "a");
- fprintf(tfp, "\n{%% children %%}\n\n");
- fclose(tfp);
- }
- }
-
- // Close any previously opened files...
- if (newFile != NULL)
- {
- fclose(newFile);
- newFile = NULL;
- }
-
- if (level == 0)
- {
- // Parts don't have any content...
- strcpy(temp, title);
- MakeFilename(temp);
- sprintf(level1File, "_manual.munge/%02d_%s", part, temp);
- mkdir(level1File, 0777);
-
- // Set up the "part" level of TOC link
- sprintf(partFN, "%s", temp);
- fprintf(toc, "<h2>Part %s: %s</h2>\n", roman[part], title);
-
- // Make the file expected at this level...
- sprintf(temp, "%s.html", level1File);
- FILE * tfp = fopen(temp, "w");
- fprintf(tfp, "---\n");
- fprintf(tfp, "title: %s\n", title);
-
- if (strlen(shortTitle) > 0)
- fprintf(tfp, "menu_title: %s\n", shortTitle);
-
- fprintf(tfp, "---\n");
- fprintf(tfp, "\n{%% children %%}\n\n");
- fclose(tfp);
- }
- else if (level == 1)
- {
- strcpy(temp, title);
- MakeFilename(temp);
- sprintf(level2File, "%s/%02d_%s", level1File, chapter, temp);
- mkdir(level2File, 0777);
-
- // Set up the "chapter" part of the TOC link
- sprintf(chapterFN, "%s", temp);
- fprintf(toc, " <p id=chapter>Ch. %d: <a href=\"/%s/%s/\">%s</a></p>\n", chapter, partFN, chapterFN, title);
-
- // If there's an include file, copy it...
- if (strlen(inclFile) > 0)
- {
- sprintf(temp, "include/%s", inclFile);
- sprintf(temp2, "%s.html", level2File);
- CopyFile(temp, temp2);
- }
- else
- {
- // Make the file expected at this level...
- sprintf(temp, "%s.html", level2File);
- newFile = fopen(temp, "w");
- fprintf(newFile, "---\n");
- fprintf(newFile, "title: %s\n", title);
-
- if (strlen(shortTitle) > 0)
- fprintf(newFile, "menu_title: %s\n", shortTitle);
-
- fprintf(newFile, "---\n\n");
- }
- }
- else if (level == 2)
- {
- strcpy(temp, title);
- MakeFilename(temp);
- sprintf(level3File, "%s/%02d_%s.html", level2File, subchapter, temp);
-
- // Make the file expected at this level...
-
- // Make the link
- sprintf(scLink, "/%s/%s/%s/", partFN, chapterFN, temp);
- fprintf(toc, " <a id=subchapter href=\"%s\">%s</a><br />\n", scLink, title);
-
- // If there's an include file, copy it...
- if (strlen(inclFile) > 0)
- {
- sprintf(temp, "include/%s", inclFile);
- CopyFile(temp, level3File);
- }
- else
- {
- // Otherwise, stream it out of the master document
- newFile = fopen(level3File, "w");
- fprintf(newFile, "---\n");
- fprintf(newFile, "title: %s\n", title);
-
- if (strlen(shortTitle) > 0)
- fprintf(newFile, "menu_title: %s\n", shortTitle);
-
- if (strlen(style) > 0)
- fprintf(newFile, "style: %s\n", style);
-
- fprintf(newFile, "---\n\n");
- }
- }
- }
- else
- {
- if (((level == 1) || (level == 2)) && (newFile != NULL))
- fprintf(newFile, "%s", buffer);
- }
-
- // Make sure no spurious garbage signals a false positive
- buffer[0] = 0;
- }
-
- printf("\n\nProcessed %i lines.\n", lineCount);
-
- fclose(master);
- fclose(toc);
-
- if (newFile)
- fclose(newFile);
-
- return 0;
-}
-