2 // Small program to 'explode' the master document automagically into separate
3 // files in the include/ directory.
6 // (C) 2017 Underground Software
12 #include <sys/stat.h> // For mkdir()
13 #include <sys/types.h>
16 // Global variable (OMG YOU EVIL BASTARD!!)
17 char buffer[1024000], keyword[1024], token[1024];
18 char title[1024], shortTitle[1024], inclFile[1024], style[1024];
19 int level = 0, lastLevel = -1;
20 int lineCount = 0, startLine, sectionLineCount, fileCount = 0;
21 int part = 0, chapter = 0, subchapter = 0;
24 FILE * newFile = NULL;
25 char level1File[1024], level2File[1024], level3File[1024], temp[1024];
26 char partFN[1024], chapterFN[1024], scLink[4096];
29 void MakeFilename(char * fn)
33 for(int i=0; i<l; i++)
37 else if (fn[i] >= 'A' && fn[i] <= 'Z')
39 else if (fn[i] >= 'a' && fn[i] <= 'z')
41 else if (fn[i] >= '0' && fn[i] <= '9')
49 bool ParseHeader(FILE * file)
53 // If we hit the EOF before finishing, something went horribly wrong
57 fgets(buffer, 1023999, file);
60 // If we're seeing the end of header sentinel, return; we're done.
61 if (strncmp(buffer, "---", 3) == 0)
64 sscanf(buffer, "%[^:]: %[^\n]", keyword, token);
66 if (strcmp(keyword, "title") == 0)
70 else if (strcmp(keyword, "part") == 0)
73 int len = strlen(token);
78 level = 1, chapter++, subchapter = 0;
80 level = 2, subchapter++;
82 level = -1; // Something went wrong
84 else if (strcmp(keyword, "include") == 0)
86 strcpy(inclFile, token);
88 else if (strcmp(keyword, "menu_title") == 0)
90 strcpy(shortTitle, token);
92 else if (strcmp(keyword, "style") == 0)
96 else if (strcmp(keyword, "exclude") == 0)
98 // Don't care about the token, just the keyword
102 printf("Unknown keyword '%s' (token: %s)\n", keyword, token);
105 // If we end up here, something went horribly wrong...
110 int main(int argc, char * argv[])
112 // First, check to see if this has been run here already.
113 FILE * fp = fopen("master-doc.txt", "r");
114 fgets(buffer, 1023999, fp);
117 if (strncmp(buffer, "<!-- exploded -->", 17) == 0)
119 printf("Master file has already been exploded.\n");
123 // First, rename the master document
124 rename("master-doc.txt", "master-doc.bak");
126 // Then open the .bak file
127 FILE * master = fopen("master-doc.bak", "r");
131 printf("Could not open master doc (master-doc.txt) file!\n");
135 // Create new master document
136 FILE * exp = fopen("master-doc.txt", "w");
140 printf("Could not open 'master-doc.txt' file!\n");
145 fprintf(exp, "<!-- exploded -->\n");
147 while (!feof(master))
149 fgets(buffer, 1023999, master);
152 // Look for start of file marker
153 if (strncmp(buffer, "---", 3) == 0)
155 // Reset the "short" title, include file & sytle
161 if (!ParseHeader(master))
163 printf("Something went horribly wrong with the header parsing! Aborting!\n");
167 // Close any previously opened files...
174 // We finished parsing our keyword block, now do something about
177 // temp, for explode only:
178 if (strlen(inclFile) > 0)
183 // Parts don't have any content...
185 // Set up the "part" level of TOC link
186 sprintf(partFN, "%s", temp);
188 // Set up content for the exploded part level
189 fprintf(exp, "\n---\n");
190 fprintf(exp, "title: %s\n", title);
192 if (strlen(shortTitle) > 0)
193 fprintf(exp, "menu_title: %s\n", shortTitle);
195 fprintf(exp, "part: part\n");
196 fprintf(exp, "---\n\n\n");
200 // Make a filename from the title (not short title!)
201 strcpy(chapterFN, title);
202 MakeFilename(chapterFN);
204 // Set up content for the exploded chapter level
205 fprintf(exp, "---\n");
206 fprintf(exp, "title: %s\n", title);
208 if (strlen(shortTitle) > 0)
209 fprintf(exp, "menu_title: %s\n", shortTitle);
211 if (strlen(inclFile) > 0)
212 fprintf(exp, "include: %s\n", inclFile);
214 fprintf(exp, "include: %s.html\n", chapterFN);
216 // If it was already an include file, mark it to stay in include/
218 fprintf(exp, "exclude: yes\n");
220 fprintf(exp, "part: chapter\n");
221 fprintf(exp, "---\n\n");
223 // Make the file expected at this level (but only if not
228 sprintf(temp, "include/%s.html", chapterFN);
229 newFile = fopen(temp, "w");
230 fprintf(newFile, "---\n");
231 fprintf(newFile, "title: %s\n", title);
233 if (strlen(shortTitle) > 0)
234 fprintf(newFile, "menu_title: %s\n", shortTitle);
236 fprintf(newFile, "---\n");
241 strcpy(scLink, title);
242 MakeFilename(scLink);
244 // Set up content for the exploded subchapter level
245 fprintf(exp, "---\n");
246 fprintf(exp, "title: %s\n", title);
248 if (strlen(shortTitle) > 0)
249 fprintf(exp, "menu_title: %s\n", shortTitle);
251 if (strlen(inclFile) > 0)
252 fprintf(exp, "include: %s\n", inclFile);
254 fprintf(exp, "include: %s.html\n", scLink);
256 // If it was already an include file, mark it to stay in include/
258 fprintf(exp, "exclude: yes\n");
260 fprintf(exp, "part: subchapter\n");
261 fprintf(exp, "---\n\n");
266 sprintf(temp, "include/%s.html", scLink);
267 newFile = fopen(temp, "w");
268 fprintf(newFile, "---\n");
269 fprintf(newFile, "title: %s\n", title);
271 if (strlen(shortTitle) > 0)
272 fprintf(newFile, "menu_title: %s\n", shortTitle);
274 if (strlen(style) > 0)
275 fprintf(newFile, "style: %s\n", style);
277 fprintf(newFile, "---\n");
283 if (((level == 1) || (level == 2)) && (newFile != NULL))
284 fprintf(newFile, "%s", buffer);
287 // Kill the buffer to prevent false positives...
291 printf("\nProcessed %i lines.\n", lineCount);
292 printf("Exploded master document into %i files.\n", fileCount);
300 // Finally, remove the .bak file:
301 remove("master-doc.bak");