]> Shamusworld >> Repos - ardour-manual-diverged/blobdiff - explode.cpp
Added explode/implode convenience commands.
[ardour-manual-diverged] / explode.cpp
diff --git a/explode.cpp b/explode.cpp
new file mode 100644 (file)
index 0000000..7d5cc32
--- /dev/null
@@ -0,0 +1,305 @@
+//
+// Small program to 'explode' the master document automagically into separate
+// files in the include/ directory.
+//
+// by James Hammons
+// (C) 2017 Underground Software
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>          // For mkdir()
+#include <sys/types.h>
+
+
+// Global variable (OMG YOU EVIL 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, fileCount = 0;
+int part = 0, chapter = 0, subchapter = 0;
+bool first = true;
+bool nomove = false;
+FILE * newFile = NULL;
+char level1File[1024], level2File[1024], level3File[1024], temp[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] = '_';
+       }
+}
+
+
+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[])
+{
+       // First, check to see if this has been run here already.
+       FILE * fp = fopen("master-doc.txt", "r");
+       fgets(buffer, 1023999, fp);
+       fclose(fp);
+
+       if (strncmp(buffer, "<!-- exploded -->", 17) == 0)
+       {
+               printf("Master file has already been exploded.\n");
+               return 0;
+       }
+
+       // First, rename the master document
+       rename("master-doc.txt", "master-doc.bak");
+
+       // Then open the .bak file
+       FILE * master = fopen("master-doc.bak", "r");
+
+       if (master == NULL)
+       {
+               printf("Could not open master doc (master-doc.txt) file!\n");
+               return -1;
+       }
+
+       // Create new master document
+       FILE * exp = fopen("master-doc.txt", "w");
+
+       if (exp == NULL)
+       {
+               printf("Could not open 'master-doc.txt' file!\n");
+               fclose(master);
+               return -1;
+       }
+
+       fprintf(exp, "<!-- exploded -->\n");
+
+       while (!feof(master))
+       {
+               fgets(buffer, 1023999, master);
+               lineCount++;
+
+               // Look for start of file marker
+               if (strncmp(buffer, "---", 3) == 0)
+               {
+                       // 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;
+                       }
+
+                       // Close any previously opened files...
+                       if (newFile != NULL)
+                       {
+                               fclose(newFile);
+                               newFile = NULL;
+                       }
+
+                       // We finished parsing our keyword block, now do something about
+                       // it... :-P
+
+                       // temp, for explode only:
+                       if (strlen(inclFile) > 0)
+                               nomove = true;
+
+                       if (level == 0)
+                       {
+                               // Parts don't have any content...
+
+                               // Set up the "part" level of TOC link
+                               sprintf(partFN, "%s", temp);
+
+                               // Set up content for the exploded part level
+                               fprintf(exp, "\n---\n");
+                               fprintf(exp, "title: %s\n", title);
+
+                               if (strlen(shortTitle) > 0)
+                                       fprintf(exp, "menu_title: %s\n", shortTitle);
+
+                               fprintf(exp, "part: part\n");
+                               fprintf(exp, "---\n\n\n");
+                       }
+                       else if (level == 1)
+                       {
+                               // Make a filename from the title (not short title!)
+                               strcpy(chapterFN, title);
+                               MakeFilename(chapterFN);
+
+                               // Set up content for the exploded chapter level
+                               fprintf(exp, "---\n");
+                               fprintf(exp, "title: %s\n", title);
+
+                               if (strlen(shortTitle) > 0)
+                                       fprintf(exp, "menu_title: %s\n", shortTitle);
+
+                               if (strlen(inclFile) > 0)
+                                       fprintf(exp, "include: %s\n", inclFile);
+                               else
+                                       fprintf(exp, "include: %s.html\n", chapterFN);
+
+                               // If it was already an include file, mark it to stay in include/
+                               if (nomove)
+                                       fprintf(exp, "exclude: yes\n");
+
+                               fprintf(exp, "part: chapter\n");
+                               fprintf(exp, "---\n\n");
+
+                               // Make the file expected at this level (but only if not
+                               // included)...
+                               if (nomove == false)
+                               {
+                                       fileCount++;
+                                       sprintf(temp, "include/%s.html", chapterFN);
+                                       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");
+                               }
+                       }
+                       else if (level == 2)
+                       {
+                               strcpy(scLink, title);
+                               MakeFilename(scLink);
+
+                               // Set up content for the exploded subchapter level
+                               fprintf(exp, "---\n");
+                               fprintf(exp, "title: %s\n", title);
+
+                               if (strlen(shortTitle) > 0)
+                                       fprintf(exp, "menu_title: %s\n", shortTitle);
+
+                               if (strlen(inclFile) > 0)
+                                       fprintf(exp, "include: %s\n", inclFile);
+                               else
+                                       fprintf(exp, "include: %s.html\n", scLink);
+
+                               // If it was already an include file, mark it to stay in include/
+                               if (nomove)
+                                       fprintf(exp, "exclude: yes\n");
+
+                               fprintf(exp, "part: subchapter\n");
+                               fprintf(exp, "---\n\n");
+
+                               if (nomove == false)
+                               {
+                                       fileCount++;
+                                       sprintf(temp, "include/%s.html", scLink);
+                                       newFile = fopen(temp, "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");
+                               }
+                       }
+               }
+               else
+               {
+                       if (((level == 1) || (level == 2)) && (newFile != NULL))
+                               fprintf(newFile, "%s", buffer);
+               }
+
+               // Kill the buffer to prevent false positives...
+               buffer[0] = 0;
+       }
+
+       printf("\nProcessed %i lines.\n", lineCount);
+       printf("Exploded master document into %i files.\n", fileCount);
+
+       fclose(master);
+       fclose(exp);
+
+       if (newFile)
+               fclose(newFile);
+
+       // Finally, remove the .bak file:
+       remove("master-doc.bak");
+
+       return 0;
+}
+