diff options
Diffstat (limited to 'tools/transpiler/transpiler.cpp')
-rw-r--r-- | tools/transpiler/transpiler.cpp | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/tools/transpiler/transpiler.cpp b/tools/transpiler/transpiler.cpp new file mode 100644 index 0000000..c27ce51 --- /dev/null +++ b/tools/transpiler/transpiler.cpp @@ -0,0 +1,255 @@ +#include "MyString.h" +#include "List.h" +#include "Logger.h" +#include "replacer.h" +#include <cstdio> +#include <vector> +#include <cstring> + +struct InnerCategory { + bool isLabel = false; + String label; + String path; + + void toCode(StringBuilder& sb) { + if (isLabel) { + sb.format("\t\t\t\t\t<li><label>%s</label></li>\n", label.getValue()); + } else { + sb.format("\t\t\t\t\t<li><a title=\"%s\" href=\"%s\">%s</a></li>\n", path.getValue(), path.getValue(), label.getValue()); + } + } + + void free() { + label.free(); + path.free(); + } +}; + +struct OuterCategory { + String outerName; + String outerSymbol; + List<InnerCategory> items; + + void toCode(StringBuilder& sb) { + sb.addStr("\t\t\t<li>\n"); + sb.format("\t\t\t\t<span>%s<span>%s</span></span>\n", outerSymbol.getValue(), outerName.getValue()); + sb.addStr("\t\t\t\t<ul class=\"inner-tree\">\n"); + + FOREACH(items) { + value->toCode(sb); + } + + sb.addStr("\t\t\t\t</ul>\n"); + sb.addStr("\t\t\t</li>\n"); + } + + void reset() { + outerName.free(); + outerSymbol.free(); + items.clear(); + } + + void free() { + outerName.free(); + outerSymbol.free(); + + FOREACH(items) { + value->free(); + } + items.deallocate(); + } +}; + +int main() { + logger_info("Running transpiler"); + FILE* pagesFile = fopen("tools/transpiler/pages.txt", "r+"); + + char * cLine = NULL; + size_t len = 0; + ssize_t read; + + StringBuilder sb; + StringBuilder otherSb; + + sb.addStr("\t\t<nav>\n\t\t<ul class=\"outer-tree\">\n"); + sb.addStr("\t\t\t<li><a href=\"/\">Introduction</a></li>\n"); + + bool isFirst = true; + OuterCategory oc; + List<String> servedFiles; + + servedFiles.add("./index.html"); + while ((read = getline(&cLine, &len, pagesFile)) != -1) { + char* line = cLine; + + int indent = 0; + while (line[0] == '>') { + line++; + indent++; + } + + switch (indent) { + case 0: { + if (!isFirst) { + oc.toCode(sb); + } + oc.reset(); + + isFirst = false; + // Outer tree item + while (line[0] != ' ') { + otherSb.addChar(line[0]); + line++; + } + line++; + + oc.outerSymbol = otherSb.toString(); + otherSb.clear(); + + while (line[0] != '\n') { + if (line[0] != '\"') { + otherSb.addChar(line[0]); + } + line++; + } + + oc.outerName = otherSb.toString(); + logger_info(oc.outerName.getValue()); + otherSb.clear(); + + break; + } + case 1: { + InnerCategory ic; + ic.isLabel = true; + while (line[0] != '\n') { + if (line[0] != '\"') { + otherSb.addChar(line[0]); + } + line++; + } + ic.label = otherSb.toString(); + otherSb.clear(); + oc.items.add(ic); + + break; + } + case 2: { + InnerCategory ic; + ic.isLabel = false; + + while (line[0] != ' ') { + otherSb.addChar(line[0]); + line++; + } + line++; + + ic.path = otherSb.toString(); + otherSb.insert('.', 0); + String pathCopy = otherSb.toString(); + servedFiles.add(pathCopy); + otherSb.clear(); + + while (line[0] != '\n') { + if (line[0] != '\"') { + otherSb.addChar(line[0]); + } + line++; + } + + ic.label = otherSb.toString(); + otherSb.clear(); + oc.items.add(ic); + + break; + } + } + } + + oc.toCode(sb); + sb.addStr("\t\t</ul>\n\t\t</nav>\n"); + oc.reset(); + fclose(pagesFile); + + String navbarRetval = sb.toString(); + sb.clear(); + + logger_info("Creating served files"); + + // Create the header + FOREACH(servedFiles) { + otherSb.clear(); + otherSb.format("%s.content", value->getValue()); + String contentFileName = otherSb.toString(); + FILE* contentFile = fopen(contentFileName.getValue(), "r+"); + if (contentFile == NULL) { + logger_warning("Could not output file, most likely unimplemented: %s", contentFileName.getValue()); + continue; + } + + logger_info("Outputting file: %s", contentFileName.getValue()); + + // Header + sb.addStr("<!DOCTYPE html>\n" + "<html lang=\"en\">\n" + "\t<head>\n" + "\t\t<meta charset=\"utf-8\">\n" + "\t\t<link rel=\"stylesheet\" href=\"/index.css\">\n" + "\t\t<title>Physics for Games</title>\n" + "\t\t<link rel=\"shortcut icon\" href=\"/favicon/favicon.ico\" type=\"image/x-icon\">\n" + "\t\t<meta name=\"description\" content=\"A place to learn all about real-time physics simulations through descriptions, code snippets, and example programs all written in C++ and OpenGL.\">\n" + "\t\t<meta name=\"og:description\" content=\"A place to learn all about real-time physics simulations through descriptions, code snippets, and example programs all written in C++ and OpenGL.\">\n" + "\t</head>\n" + "\t<body>\n" + "\t\t<header>\n" + "\t\t\t<h1><a title=\"physicsforgames.com\" href=\"/\">Physics for Games</a></h1>\n" + "\t\t</header>\n" + "\t\t<main>\n"); + + // Write navigation bar + sb.addStr(navbarRetval.getValue()); + // Read body + + fseek(contentFile, 0, SEEK_END); + long fsize = ftell(contentFile); + fseek(contentFile, 0, SEEK_SET); + + char* bodyContent = new char[fsize + 1]; + fread(bodyContent, 1, fsize, contentFile); + bodyContent[fsize] = '\0'; + + auto processedBody = insertCodeSnippets(contentFileName.getValue(), bodyContent); + + sb.addStr(processedBody.c_str()); + delete [] bodyContent; + + + contentFileName.free(); + fclose(contentFile); + + // Footer + sb.addStr("\t\t</main>\n" + "\t</body>\n" + "</html>\n"); + + FILE* outFile = fopen(value->getValue(), "w+"); + String outStr = sb.toString(); + fwrite(outStr.getValue(), 1, outStr.length, outFile); + outStr.free(); + fclose(outFile); + sb.clear(); + } + + logger_info("Outputting files to their proper directories..."); + sb.free(); + navbarRetval.free(); + otherSb.free(); + + FOREACH(servedFiles) { + value->free(); + } + + servedFiles.deallocate(); + + return 0; +} |