]> Shamusworld >> Repos - ardour-manual-diverged/blob - munge.cpp
Added appropriate "fixme"s.
[ardour-manual-diverged] / munge.cpp
1 //
2 // Program to massage the master doc file to spit out a bunch of little files
3 // for the Ruby build script...
4 //
5 // by James Hammons
6 // (C) 2016 Underground Software
7 //
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/stat.h>           // For mkdir()
13 #include <sys/types.h>
14
15
16 // Global variables (ZOMG YOU HIDEOUS 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;
21 int part = 0, chapter = 0, subchapter = 0;
22 bool first = true, nomove = false;
23 FILE * newFile = NULL;
24 char level1File[1024], level2File[1024], level3File[1024], temp[1024], temp2[1024];
25 char partFN[1024], chapterFN[1024], scLink[4096];
26
27
28 void MakeFilename(char * fn)
29 {
30         int l = strlen(fn);
31
32         for(int i=0; i<l; i++)
33         {
34                 if (fn[i] == ' ')
35                         fn[i] = '-';
36                 else if (fn[i] >= 'A' && fn[i] <= 'Z')
37                         fn[i] |= 0x20;
38                 else if (fn[i] >= 'a' && fn[i] <= 'z')
39                         ;
40                 else if (fn[i] >= '0' && fn[i] <= '9')
41                         ;
42                 else
43                         fn[i] = '_';
44         }
45 }
46
47
48 //
49 // There's probably posix function to do this, if you find it, feel free to
50 // nuke this crap
51 //
52 void CopyFile(char * from, char * to)
53 {
54         FILE * fromFile = fopen(from, "r");
55
56         if (fromFile == NULL)
57         {
58                 printf("\n\nCould not open file '%s' for reading! Aborting!!\n", from);
59                 exit(1);
60         }
61
62         FILE * toFile = fopen(to, "w");
63
64         if (toFile == NULL)
65         {
66                 printf("\n\nCould not open file '%s' for writing! Aborting!!\n", to);
67                 exit(1);
68         }
69
70         fseek(fromFile, 0, SEEK_END);
71         long length = ftell(fromFile);
72         rewind(fromFile);
73
74         for(long i=0; i<length; i++)
75                 fputc(fgetc(fromFile), toFile);
76
77         fclose(toFile);
78         fclose(fromFile);
79 }
80
81
82 bool ParseHeader(FILE * file)
83 {
84         while (true)
85         {
86                 // If we hit the EOF before finishing, something went horribly wrong
87                 if (feof(file))
88                         break;
89
90                 fgets(buffer, 1023999, file);
91                 lineCount++;
92
93                 // If we're seeing the end of header sentinel, return; we're done.
94                 if (strncmp(buffer, "---", 3) == 0)
95                         return true;
96
97                 sscanf(buffer, "%[^:]: %[^\n]", keyword, token);
98
99                 if (strcmp(keyword, "title") == 0)
100                 {
101                         strcpy(title, token);
102                 }
103                 else if (strcmp(keyword, "part") == 0)
104                 {
105                         lastLevel = level;
106                         int len = strlen(token);
107
108                         if (len == 4)
109                                 level = 0, part++;
110                         else if (len == 7)
111                                 level = 1, chapter++, subchapter = 0;
112                         else if (len == 10)
113                                 level = 2, subchapter++;
114                         else
115                                 level = -1;  // Something went wrong
116                 }
117                 else if (strcmp(keyword, "include") == 0)
118                 {
119                         strcpy(inclFile, token);
120                 }
121                 else if (strcmp(keyword, "menu_title") == 0)
122                 {
123                         strcpy(shortTitle, token);
124                 }
125                 else if (strcmp(keyword, "style") == 0)
126                 {
127                         strcpy(style, token);
128                 }
129                 else if (strcmp(keyword, "exclude") == 0)
130                 {
131                         // Don't care about the token, just the keyword
132                         nomove = true;
133                 }
134                 else
135                         printf("Unknown keyword '%s' (token: %s)\n", keyword, token);
136         }
137
138         // If we end up here, something went horribly wrong...
139         return false;
140 }
141
142
143 int main(int argc, char * argv[])
144 {
145         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" };
146
147         FILE * master = fopen("master-doc.txt", "r");
148
149         if (master == NULL)
150         {
151                 printf("Could not open master doc (master-doc.txt) file!\n");
152                 return -1;
153         }
154
155         FILE * toc = fopen("_manual/00_toc.html", "w");
156
157         if (toc == NULL)
158         {
159                 printf("Could not open TOC file!\n");
160                 fclose(master);
161                 return -1;
162         }
163
164         fprintf(toc, "---\n");
165         fprintf(toc, "title: Ardour Table of Contents\n");
166         fprintf(toc, "---\n\n");
167
168         while (!feof(master))
169         {
170                 fgets(buffer, 1023999, master);
171                 lineCount++;
172
173                 // Look for start of file marker
174                 if (strncmp(buffer, "---", 3) == 0)
175                 {
176                         if (first)
177                                 first = false;
178                         else
179                         {
180                                 sectionLineCount = lineCount - startLine;
181                                 printf(" (%d lines)\n", sectionLineCount);
182                         }
183
184                         // Reset the "short" title, include file & sytle
185                         shortTitle[0] = 0;
186                         inclFile[0] = 0;
187                         style[0] = 0;
188                         nomove = false;
189
190                         if (!ParseHeader(master))
191                         {
192                                 printf("Something went horribly wrong with the header parsing! Aborting!\n");
193                                 break;
194                         }
195
196                         // We hit the end of our keyword block, now do something
197                         // about it... :-P
198                         if (level == 0)
199                                 printf("\nPart %s: ", roman[part]);
200                         else if (level == 1)
201                                 printf("\n\tCh. %d: ", chapter);
202                         else if (level == 2)
203                                 printf("\t\t");
204
205                         printf("%s", title);
206
207                         if (strlen(inclFile) > 0)
208                                 printf(" [%s]", inclFile);
209
210                         startLine = lineCount;
211
212                         // Add appropriate suffix chapter content if needed
213                         if ((lastLevel == 1) && (level == 2))
214                         {
215                                 if (newFile != NULL)
216                                 {
217                                         fprintf(newFile, "\n{%% children %%}\n\n");
218                                 }
219                                 else
220                                 {
221                                         // If it didn't stream, it was a included file, so append to
222                                         // it directly...
223                                         sprintf(temp2, "%s.html", level2File);
224                                         FILE * tfp = fopen(temp2, "a");
225                                         fprintf(tfp, "\n{%% children %%}\n\n");
226                                         fclose(tfp);
227                                 }
228                         }
229
230                         // Close any previously opened files...
231                         if (newFile != NULL)
232                         {
233                                 fclose(newFile);
234                                 newFile = NULL;
235                         }
236
237                         if (level == 0)
238                         {
239                                 // Parts don't have any content...
240                                 strcpy(temp, title);
241                                 MakeFilename(temp);
242                                 sprintf(level1File, "_manual/%02d_%s", part, temp);
243                                 mkdir(level1File, 0777);
244
245                                 // Set up the "part" level of TOC link
246                                 sprintf(partFN, "%s", temp);
247                                 fprintf(toc, "<h2>Part %s: %s</h2>\n", roman[part], title);
248
249                                 // Make the file expected at this level...
250                                 sprintf(temp, "%s.html", level1File);
251                                 FILE * tfp = fopen(temp, "w");
252                                 fprintf(tfp, "---\n");
253                                 fprintf(tfp, "title: %s\n", title);
254
255                                 if (strlen(shortTitle) > 0)
256                                         fprintf(tfp, "menu_title: %s\n", shortTitle);
257
258                                 fprintf(tfp, "---\n");
259                                 fprintf(tfp, "\n{%% children %%}\n\n");
260                                 fclose(tfp);
261                         }
262                         else if (level == 1)
263                         {
264                                 strcpy(temp, title);
265                                 MakeFilename(temp);
266                                 sprintf(level2File, "%s/%02d_%s", level1File, chapter, temp);
267                                 mkdir(level2File, 0777);
268
269                                 // Set up the "chapter" part of the TOC link
270                                 sprintf(chapterFN, "%s", temp);
271                                 fprintf(toc, "  <p id=chapter>Ch. %d:&nbsp;&nbsp;<a href=\"/%s/%s/\">%s</a></p>\n", chapter, partFN, chapterFN, title);
272
273                                 // If there's an include file, copy it...
274                                 if (strlen(inclFile) > 0)
275                                 {
276                                         sprintf(temp, "include/%s", inclFile);
277                                         sprintf(temp2, "%s.html", level2File);
278                                         CopyFile(temp, temp2);
279                                 }
280                                 else
281                                 {
282                                         // Make the file expected at this level...
283                                         sprintf(temp, "%s.html", level2File);
284                                         newFile = fopen(temp, "w");
285                                         fprintf(newFile, "---\n");
286                                         fprintf(newFile, "title: %s\n", title);
287
288                                         if (strlen(shortTitle) > 0)
289                                                 fprintf(newFile, "menu_title: %s\n", shortTitle);
290
291                                         fprintf(newFile, "---\n\n");
292                                 }
293                         }
294                         else if (level == 2)
295                         {
296                                 strcpy(temp, title);
297                                 MakeFilename(temp);
298                                 sprintf(level3File, "%s/%02d_%s.html", level2File, subchapter, temp);
299
300                                 // Make the file expected at this level...
301
302                                 // Make the link
303                                 sprintf(scLink, "/%s/%s/%s/", partFN, chapterFN, temp);
304                                 fprintf(toc, "    <a id=subchapter href=\"%s\">%s</a><br />\n", scLink, title);
305
306                                 // If there's an include file, copy it...
307                                 if (strlen(inclFile) > 0)
308                                 {
309                                         sprintf(temp, "include/%s", inclFile);
310                                         CopyFile(temp, level3File);
311                                 }
312                                 else
313                                 {
314                                         // Otherwise, stream it out of the master document
315                                         newFile = fopen(level3File, "w");
316                                         fprintf(newFile, "---\n");
317                                         fprintf(newFile, "title: %s\n", title);
318
319                                         if (strlen(shortTitle) > 0)
320                                                 fprintf(newFile, "menu_title: %s\n", shortTitle);
321
322                                         if (strlen(style) > 0)
323                                                 fprintf(newFile, "style: %s\n", style);
324
325                                         fprintf(newFile, "---\n\n");
326                                 }
327                         }
328                 }
329                 else
330                 {
331                         if (((level == 1) || (level == 2)) && (newFile != NULL))
332                                 fprintf(newFile, "%s", buffer);
333                 }
334
335                 // Make sure no spurious garbage signals a false positive
336                 buffer[0] = 0;
337         }
338
339         printf("\n\nProcessed %i lines.\n", lineCount);
340
341         fclose(master);
342         fclose(toc);
343
344         if (newFile)
345                 fclose(newFile);
346
347         return 0;
348 }
349