From 98b74941db07f09c0665e59bbb2ef87bc51facb7 Mon Sep 17 00:00:00 2001 From: luca0N! Date: Thu, 24 Feb 2022 22:40:14 -0300 Subject: [PATCH] Add original source files --- Makefile | 49 +++++++++ src/Common.hxx | 38 +++++++ src/ConfigUtils.cxx | 167 +++++++++++++++++++++++++++++ src/ConfigUtils.hxx | 30 ++++++ src/SwgContext.hxx | 63 +++++++++++ src/SwgRuntime.cxx | 27 +++++ src/SwgRuntime.hxx | 27 +++++ src/WebsiteBuilder.cxx | 238 +++++++++++++++++++++++++++++++++++++++++ src/WebsiteBuilder.hxx | 27 +++++ src/main.cxx | 84 +++++++++++++++ 10 files changed, 750 insertions(+) create mode 100644 Makefile create mode 100644 src/Common.hxx create mode 100644 src/ConfigUtils.cxx create mode 100644 src/ConfigUtils.hxx create mode 100644 src/SwgContext.hxx create mode 100644 src/SwgRuntime.cxx create mode 100644 src/SwgRuntime.hxx create mode 100644 src/WebsiteBuilder.cxx create mode 100644 src/WebsiteBuilder.hxx create mode 100644 src/main.cxx diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..81ee390 --- /dev/null +++ b/Makefile @@ -0,0 +1,49 @@ +# Copyright (C) 2022 luca0N! +# +# This file is part of Static Website Generator (swg). +# +# Static Website Generator (swg) is free software: you can redistribute it +# and/or modify it under the terms of the version 3 of the GNU Lesser General +# Public License as published by the Free Software Foundation. +# +# Static Website Generator (swg) is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Static Website Generator (swg). If not, see +# . +# +# Contact luca0N! by e-mail: . + +PROGRAM_NAME=swg + +CXXC=g++ +CXXFLAGS=-Wall -Wextra -g -O0 -std=c++17 + +.PHONY: clean + +$(PROGRAM_NAME): build/ build/obj/ build/obj/main.o build/obj/ConfigUtils.o build/obj/WebsiteBuilder.o build/obj/SwgRuntime.o + $(CXXC) -o $(PROGRAM_NAME) build/obj/main.o build/obj/ConfigUtils.o build/obj/WebsiteBuilder.o build/obj/SwgRuntime.o + +build/obj/main.o: src/main.cxx src/ConfigUtils.hxx src/SwgContext.hxx src/WebsiteBuilder.hxx src/Common.hxx + $(CXXC) $(CXXFLAGS) -o build/obj/main.o -c src/main.cxx + +build/obj/ConfigUtils.o: src/ConfigUtils.cxx src/SwgContext.hxx src/Common.hxx + $(CXXC) $(CXXFLAGS) -o build/obj/ConfigUtils.o -c src/ConfigUtils.cxx + +build/obj/WebsiteBuilder.o: src/WebsiteBuilder.hxx src/WebsiteBuilder.cxx src/SwgRuntime.hxx src/Common.hxx + $(CXXC) $(CXXFLAGS) -o build/obj/WebsiteBuilder.o -c src/WebsiteBuilder.cxx + +build/obj/SwgRuntime.o: src/SwgRuntime.hxx src/SwgRuntime.cxx + $(CXXC) $(CXXFLAGS) -o build/obj/SwgRuntime.o -c src/SwgRuntime.cxx + +build/: + mkdir -p build/ + +build/obj/: + mkdir -p build/obj/ + +clean: + rm -rfv build/ $(PROGRAM_NAME) diff --git a/src/Common.hxx b/src/Common.hxx new file mode 100644 index 0000000..3651593 --- /dev/null +++ b/src/Common.hxx @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 luca0N! + * + * This file is part of Static Website Generator (swg). + * + * Static Website Generator (swg) is free software: you can redistribute it + * and/or modify it under the terms of the version 3 of the GNU Lesser General + * Public License as published by the Free Software Foundation. + * + * Static Website Generator (swg) is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Static Website Generator (swg). If not, see + * . + * + * Contact luca0N! by e-mail: . + */ + +#pragma once + +#define PROGRAM_NAME "SWG" +#define PROGRAM_VERSION 1 +#define PROGRAM_VERSION_NAME "0.1-dev" +#define PROGRAM_COPYRIGHT "luca0N!" +#define PROGRAM_COPYRIGHT_YEARS "2022" + +#define RETURN_SUCCESSFUL 0 + +#define RETURN_FAILED_INVALID_SYNTAX 1 +#define RETURN_FAILED_CONFIG_INVALID_SYNTAX 2 +#define RETURN_FAILED_INVALID_DIRECTORY 3 +#define RETURN_FAILED_WEBSITE_BUILD_EXISTS 4 + +#define RETURN_FAILED_UNKNOWN_ERROR 10 + diff --git a/src/ConfigUtils.cxx b/src/ConfigUtils.cxx new file mode 100644 index 0000000..c0d2436 --- /dev/null +++ b/src/ConfigUtils.cxx @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2022 luca0N! + * + * This file is part of Static Website Generator (swg). + * + * Static Website Generator (swg) is free software: you can redistribute it + * and/or modify it under the terms of the version 3 of the GNU Lesser General + * Public License as published by the Free Software Foundation. + * + * Static Website Generator (swg) is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Static Website Generator (swg). If not, see + * . + * + * Contact luca0N! by e-mail: . + */ + +#include "ConfigUtils.hxx" + +#include +#include +#include + +#include "Common.hxx" + +void parse_config(SwgContext *ctx, std::string const &path) { + std::string ctxCfgPath = path; + ctxCfgPath += "/swg.cfg"; + + FILE *ctxCfgFile = fopen(ctxCfgPath.c_str(), "r"); + + if (ctxCfgFile == NULL) { + std::cerr << "error: cannot open swg.cfg file, are you sure " + << path << " is a valid SWG directory?" << std::endl; + perror(ctxCfgPath.c_str()); + exit(RETURN_FAILED_INVALID_DIRECTORY); + } + + int buflen = 16; + char cbuf[buflen]; + + // Yes, this looks ugly, but it works for now. Will probably optimize + // this in the future :) + // + // TODO: Optimize config file interpretation + + std::list lines = { "" }; + while (fgets(cbuf, buflen, ctxCfgFile) != NULL) { + int eol = -1; + for (int c = 0; c < buflen; c++) { + if (cbuf[c] == '\0') { + break; + } else if (cbuf[c] == '\n') { + eol = c; + break; + } + } + if (eol > -1) { + cbuf[eol] = '\0'; + *(--lines.end()) += cbuf; + lines.insert(lines.end(), ""); + } else + *(--lines.end()) += cbuf; + } + + fclose(ctxCfgFile); + + std::cout << "Done loading configuration file in memory" << std::endl; + + // Parse configuration file + + enum ConfigNamespace { General, Blogs }; + ConfigNamespace ns; + + int blogCount = 0; + Blog *currentBlog = NULL; // (Blog*) malloc(sizeof(Blog)); + + // currentBlog->name = "asd"; + + for (std::string line : lines) { + // Skip comment lines + if (line.c_str()[0] == '#') + continue; + + if (line.c_str()[0] == '[') { + if (line == "[General]") { + ns = General; + continue; + } else if (line == "[Blogs]") { + ns = Blogs; + continue; + } else { + std::cerr << "error: unknown namespace in config file: " << line << std::endl; + exit(RETURN_FAILED_CONFIG_INVALID_SYNTAX); + } + } + + // Skip empty lines + if (line == "") continue; + + int end = line.find("="); + std::string k = line.substr(0, end), + v = line.substr(end + 2, + (line.length() - 1) - (end + 2)); + + switch (ns) { + case General: + if (k == "WebsiteName") + ctx->websiteName = v; + else if (k == "WebsitePublisher") + ctx->websitePublisher = v; + else if (k == "WebsiteCopyrightHolder") + ctx->websiteCopyrightHolder = v; + else if (k == "WebsiteCopyrightYears") + ctx->websiteCopyrightYears = v; + else if (k == "websiteContentLicense") + ctx->websiteContentLicense = v; + else + std::cerr << "warning: unknown key in namespace \"General\": " << k << std::endl; + continue; + case Blogs: + // FIXME: This code only accepts up to 9 blogs. + if (line.substr(0, 4) == "Blog") { + // Check No. + int blogNo = atoi(line.substr(4, 1).c_str()); + if (blogNo != blogCount && + blogNo != blogCount +1){ + std::cerr << "error: blog declaration must be incremental (received " + << blogNo << " instead of " << blogCount << " or " << blogCount + 1 + << ")" << std::endl; + exit(RETURN_FAILED_CONFIG_INVALID_SYNTAX); + } else if (blogNo == blogCount + 1) { + blogCount++; + if (currentBlog != NULL) ctx->blogs.push_back(currentBlog); + currentBlog = (Blog*) malloc(sizeof(Blog)); + // Clear allocated memory + memset(currentBlog, 0, sizeof(Blog)); + } + + assert(currentBlog != NULL); + //std::cout << "Attempting to set K/V" << std::endl; + + if (k.substr(5) == "Path") { + //std::cout << "Setting path (" << v << ") for " << blogCount << std::endl; + strncpy(currentBlog->path, v.c_str(), sizeof(currentBlog->path)); + } else if (k.substr(5) == "Name") { + //std::cout << "Setting name (" << v << ") for " << blogCount << std::endl; + strncpy(currentBlog->name, v.c_str(), sizeof(currentBlog->name)); + } else if (k.substr(5) == "Dir") { + strncpy(currentBlog->dir, v.c_str(), sizeof(currentBlog->dir)); + } else { + std::cerr << "warning: unknown key in namespace \"Blogs\": " << k << "\n"; + } + } + continue; + } + } + if (currentBlog != NULL) ctx->blogs.push_back(currentBlog); + /*std::cout << "Loaded " << blogCount << " blogs into memory" << std::endl; + for (Blog *b : ctx->blogs) { + std::cout << "\t" << b->name << ": " << b->path << std::endl; + }*/ +} diff --git a/src/ConfigUtils.hxx b/src/ConfigUtils.hxx new file mode 100644 index 0000000..7a63a73 --- /dev/null +++ b/src/ConfigUtils.hxx @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 luca0N! + * + * This file is part of Static Website Generator (swg). + * + * Static Website Generator (swg) is free software: you can redistribute it + * and/or modify it under the terms of the version 3 of the GNU Lesser General + * Public License as published by the Free Software Foundation. + * + * Static Website Generator (swg) is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Static Website Generator (swg). If not, see + * . + * + * Contact luca0N! by e-mail: . + */ + +#pragma once + +#include +#include + +#include "SwgContext.hxx" + +void parse_config(SwgContext *ctx, std::string const &path); + diff --git a/src/SwgContext.hxx b/src/SwgContext.hxx new file mode 100644 index 0000000..df0d3de --- /dev/null +++ b/src/SwgContext.hxx @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2022 luca0N! + * + * This file is part of Static Website Generator (swg). + * + * Static Website Generator (swg) is free software: you can redistribute it + * and/or modify it under the terms of the version 3 of the GNU Lesser General + * Public License as published by the Free Software Foundation. + * + * Static Website Generator (swg) is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Static Website Generator (swg). If not, see + * . + * + * Contact luca0N! by e-mail: . + */ + +#pragma once + +#include +#include + +struct Blog { + char name[64], + path[64], + dir[64]; + int test; +}; + +struct SwgContext { + std::string websiteName, + websitePublisher, + websiteCopyrightHolder, + websiteCopyrightYears, + websiteContentLicense; + + // TODO: Use smart pointers + std::list blogs; +}; + +/*class SwgContext { + public: + SwgContext(); + SwgContext(std::string websiteName, std::string websitePublisher, std::string copyrightHolder, std::string copyrightYears, std::string contentLicense); + + + private: + std::string websiteName, websitePublisher; + std::string copyrightHolder, copyrightYears, contentLicense; +}; + +class BlogEntry { + public: + BlogEntry(std::string name, std::string path); + std::string getBlogName(); + std::string getBlogPath(); + private: + std::string path, name; +};*/ diff --git a/src/SwgRuntime.cxx b/src/SwgRuntime.cxx new file mode 100644 index 0000000..3b08809 --- /dev/null +++ b/src/SwgRuntime.cxx @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2022 luca0N! + * + * This file is part of Static Website Generator (swg). + * + * Static Website Generator (swg) is free software: you can redistribute it + * and/or modify it under the terms of the version 3 of the GNU Lesser General + * Public License as published by the Free Software Foundation. + * + * Static Website Generator (swg) is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Static Website Generator (swg). If not, see + * . + * + * Contact luca0N! by e-mail: . + */ + +#include "SwgRuntime.hxx" + +bool swg_rt_global_bool(const char *name, bool ifne) { + // TODO: Check for runtime option and return it (if it's set, return ifne otherwise). + return ifne; +} diff --git a/src/SwgRuntime.hxx b/src/SwgRuntime.hxx new file mode 100644 index 0000000..18deba8 --- /dev/null +++ b/src/SwgRuntime.hxx @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2022 luca0N! + * + * This file is part of Static Website Generator (swg). + * + * Static Website Generator (swg) is free software: you can redistribute it + * and/or modify it under the terms of the version 3 of the GNU Lesser General + * Public License as published by the Free Software Foundation. + * + * Static Website Generator (swg) is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Static Website Generator (swg). If not, see + * . + * + * Contact luca0N! by e-mail: . + */ + +#pragma once + +// Utilities for options set during runtime by the end-user (i.e. through command line options). + +bool swg_rt_global_bool(const char *name, bool ifne); + diff --git a/src/WebsiteBuilder.cxx b/src/WebsiteBuilder.cxx new file mode 100644 index 0000000..38be321 --- /dev/null +++ b/src/WebsiteBuilder.cxx @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2022 luca0N! + * + * This file is part of Static Website Generator (swg). + * + * Static Website Generator (swg) is free software: you can redistribute it + * and/or modify it under the terms of the version 3 of the GNU Lesser General + * Public License as published by the Free Software Foundation. + * + * Static Website Generator (swg) is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Static Website Generator (swg). If not, see + * . + * + * Contact luca0N! by e-mail: . + */ + +#include +#include +#include +#include +#include + +#include + +#include "SwgRuntime.hxx" +#include "SwgContext.hxx" +#include "ConfigUtils.hxx" +// #include "Blog.h" +#include "Common.hxx" + +std::string blog_relative_path(std::string const &pathPrefix, std::string const &path) { + return path.substr(pathPrefix.length() - 1); +} + +std::string getFilename(std::string const &path) { + // Backwards search for directory separator. + for (int x = path.length(); x > 0; --x) { + if (path[x] == '/') + return path.substr(x + 1); + } + return path; +} + +bool isValidArticle(std::string const &pathPrefix, std::string const &path) { + return std::regex_search(blog_relative_path(pathPrefix, path), std::regex("^/\\d{4}/\\d{2}/.*\\.md")); +} + +std::filesystem::path get_output_path(std::string const &path) { + std::filesystem::path output = path; + return output /= "output"; +} + +void build_dir_structure(std::string const &path) { + // Create directory tree, which will be used for the website. + std::filesystem::path rootDir = get_output_path(path); + + // Create output directory if it doesn't exist. + try { + if(!std::filesystem::exists(rootDir)) std::filesystem::create_directory(rootDir); + } catch (std::filesystem::filesystem_error const &e) { + std::cerr << "error: fs error while generating output website directory structure on \"" + << path << "\": " << e.what() << std::endl; + exit(RETURN_FAILED_UNKNOWN_ERROR); + } + + // Check if a website has already been built. + // + // This is a safe measure to prevent overwriting an existing website + // output, but it can be skipped if explicitly asked by the end-user. + if (!swg_rt_global_bool("overwrite_existing", false)) { + std::filesystem::path websiteLock = rootDir /= ".swg_built"; + if (std::filesystem::exists(websiteLock)) { + std::cout << "error: existing website build detected, exiting...\n"; + exit(RETURN_FAILED_WEBSITE_BUILD_EXISTS); + } + } +} + +std::string get_template(std::string const &path) { + // Template lookup + std::string stPath = path; + stPath += "/__swg_template.html"; + FILE *swgTemplate = fopen(stPath.c_str(), "r"); + if (swgTemplate == NULL) { + std::cerr << "error: couldn't open the SWG HTML template file; does it exist?\n"; + perror(stPath.c_str()); + exit(RETURN_FAILED_INVALID_DIRECTORY); + } + + // Check for content placeholder + int buflen = 8; + char buf[buflen]; + std::string htmlTemplate; + while (fgets(buf, buflen, swgTemplate) != NULL) { + htmlTemplate += buf; + } + + fclose(swgTemplate); + std::cout << "Loaded HTML template into memory.\n"; + return htmlTemplate; +} + +void build_blog_structure(std::string const &path, std::string const &prefix, std::list const &articles, Blog *blog) { + std::filesystem::path obp = get_output_path(path) /= blog->dir; // Output Blog Path + try { + // Create blog directory + if (!std::filesystem::exists(obp)) std::filesystem::create_directory(obp); + } catch (std::filesystem::filesystem_error const &e) { + std::cerr << "error: failed to create directory for blog \"" << blog->name << "\": " << e.what() << std::endl; + exit(RETURN_FAILED_UNKNOWN_ERROR); + } + + for (std::string const &a : articles) { + std::string articlePath = blog_relative_path(prefix, a); + std::regex yearMonth("(\\d+)"); + auto match = std::sregex_iterator(articlePath.begin(), articlePath.end(), yearMonth); + + std::string year = match->str(), + month = (++match)->str(); + + /*std::cout << "Year for \"" << articlePath << "\": " << year << "\n"; + std::cout << "Month for \"" << articlePath << "\": " << month << "\n";*/ + + // TODO: This code could be optimized by removing directory + // checks for every single article. Instead, add + // directory-checks for years and months to a queue (skipping + // existing ones) and then checking and creating the + // directories later as needed. + try { + // Create directory for the year of this article if it doesn't exist. + std::filesystem::path oad = obp /= year; // Output Article Directory + if (!std::filesystem::exists(oad)) std::filesystem::create_directory(oad); + + // Do the same for the article month. + oad /= month; + if (!std::filesystem::exists(oad)) std::filesystem::create_directory(oad); + + // Now create the article file. + oad /= getFilename(a); + FILE *articleOutput = fopen(oad.string().c_str(), "w"); + FILE *articleFile = fopen(a.c_str(), "r"); + + std::string articleContents; + + int buflen = 512; + char buf[buflen]; + + while (fgets(buf, buflen, articleFile) != NULL) { + articleContents += buf; + } + + fclose(articleFile); + + std::string htmlTemplate = get_template(path); + // NOTE: std::regex requires the C++11 standard. + std::regex contentPlaceholder(""); + articleContents = std::regex_replace(htmlTemplate, contentPlaceholder, articleContents); + + fputs(articleContents.c_str(), articleOutput); + + fclose(articleOutput); + } catch (std::filesystem::filesystem_error const &e) { + std::cerr << "error: failed to create directory for an article from blog \"" + << blog->name << "\": " << e.what() << std::endl; + exit(RETURN_FAILED_UNKNOWN_ERROR); + } + } +} + +void build_website(SwgContext &ctx, std::string const &path) { + build_dir_structure(path); + + // Blog lookup + + bool failed = false; + + for (Blog *b : ctx.blogs) { + std::list parsedArticles = { }, + failedArticles = { }; + + // std::filesystem requires the C++17 standard. + std::string relativePath = path; + relativePath += "/"; + relativePath += b->path; + const std::filesystem::path blogPath(relativePath); + try { + for (auto const &dir_entry : std::filesystem::recursive_directory_iterator(blogPath)) { + // Directory item iteration + std::cout << "\t" << dir_entry << std::endl; + + // Check if the item is a Markdown file. + std::string filename = getFilename(dir_entry.path()); + if (dir_entry.is_regular_file() && + filename.find(".md") == filename.length() - 3) { + std::cout << "\t\tIs file: " << getFilename(dir_entry.path()) << "\n"; + // Markdown files should be insite a YYYY/MM directory. + if (!isValidArticle(relativePath, dir_entry.path())) + failedArticles.insert(failedArticles.end(), dir_entry.path()); + else parsedArticles.insert(parsedArticles.end(), dir_entry.path()); + } + } + } catch (std::filesystem::filesystem_error const &e) { + std::cerr << "error: fs error while attempting to read path for " + << b->name << ": " << e.what() << std::endl; + failed = true; + } + + /*std::cout << "Parsed " << parsedArticles << " articles;\n" << + "Failed to parse " << failedArticles << " articles\n";*/ + + for (std::string const &a : parsedArticles) + std::cout << "Parsed: " << a << "\n"; + for (std::string const &a : failedArticles) + std::cout << "Unable to parse: " << a << "\n"; + + build_blog_structure(path, relativePath, parsedArticles, b); + + free(b); + } + + if (failed) { + std::cerr << "Refusing to proceed due to previous errors\n"; + exit(RETURN_FAILED_CONFIG_INVALID_SYNTAX); + } + + // Website blog + + // Append blog to website + //ctx.appendBlog(blog1); + + // Generate website + //ctx.generateWebsite(); +} diff --git a/src/WebsiteBuilder.hxx b/src/WebsiteBuilder.hxx new file mode 100644 index 0000000..68b10e8 --- /dev/null +++ b/src/WebsiteBuilder.hxx @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2022 luca0N! + * + * This file is part of Static Website Generator (swg). + * + * Static Website Generator (swg) is free software: you can redistribute it + * and/or modify it under the terms of the version 3 of the GNU Lesser General + * Public License as published by the Free Software Foundation. + * + * Static Website Generator (swg) is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Static Website Generator (swg). If not, see + * . + * + * Contact luca0N! by e-mail: . + */ + +#pragma once + +#include "SwgContext.hxx" + +void build_website(SwgContext &ctx, std::string const &path); + diff --git a/src/main.cxx b/src/main.cxx new file mode 100644 index 0000000..5882f46 --- /dev/null +++ b/src/main.cxx @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2022 luca0N! + * + * This file is part of Static Website Generator (swg). + * + * Static Website Generator (swg) is free software: you can redistribute it + * and/or modify it under the terms of the version 3 of the GNU Lesser General + * Public License as published by the Free Software Foundation. + * + * Static Website Generator (swg) is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Static Website Generator (swg). If not, see + * . + * + * Contact luca0N! by e-mail: . + */ + +#include +#include +#include +#include +#include + +#include + +#include "SwgContext.hxx" +#include "ConfigUtils.hxx" +// #include "Blog.h" +#include "Common.hxx" +#include "WebsiteBuilder.hxx" + +void printUsage(const char *programName) { + std::cerr << programName << ": usage: " << programName << " [path]" + << std::endl; +} + +void printIntro() { + printf("%s v%s (%d)\nCopyright (C) %s %s\n\n", + PROGRAM_NAME, PROGRAM_VERSION_NAME, PROGRAM_VERSION, + PROGRAM_COPYRIGHT_YEARS, PROGRAM_COPYRIGHT); +} + +int main(int argc, char *argv[]) { + printIntro(); + + std::string path; + + // Parse cmdline options + switch (argc) { + case 1: + path = "."; + std::cout << "Assuming working directory is \".\"" + << std::endl; + break; + case 2: + path = argv[1]; + std::cout << "Using specified directory: " + << path << std::endl; + break; + default: + printUsage(argv[0]); + exit(RETURN_FAILED_INVALID_SYNTAX); + break; + } + + SwgContext ctx; + parse_config(&ctx, path); + + build_website(ctx, path); + + // Website blog + + // Append blog to website + //ctx.appendBlog(blog1); + + // Generate website + //ctx.generateWebsite(); + + return 0; +}