Add original source files

This commit is contained in:
luca0N! 2022-02-24 22:40:14 -03:00
parent 6e1bdc8870
commit 98b74941db
Signed by: luca0N
GPG Key ID: 2E7B4655CF16D7D6
10 changed files with 750 additions and 0 deletions

49
Makefile Normal file
View File

@ -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
# <https://www.gnu.org/licenses/>.
#
# Contact luca0N! by e-mail: <luca0n [at] luca0n [dot] com>.
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)

38
src/Common.hxx Normal file
View File

@ -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
* <https://www.gnu.org/licenses/>.
*
* Contact luca0N! by e-mail: <luca0n [at] luca0n [dot] com>.
*/
#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

167
src/ConfigUtils.cxx Normal file
View File

@ -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
* <https://www.gnu.org/licenses/>.
*
* Contact luca0N! by e-mail: <luca0n [at] luca0n [dot] com>.
*/
#include "ConfigUtils.hxx"
#include <iostream>
#include <cstring>
#include <cassert>
#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<std::string> 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;
}*/
}

30
src/ConfigUtils.hxx Normal file
View File

@ -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
* <https://www.gnu.org/licenses/>.
*
* Contact luca0N! by e-mail: <luca0n [at] luca0n [dot] com>.
*/
#pragma once
#include <string>
#include <list>
#include "SwgContext.hxx"
void parse_config(SwgContext *ctx, std::string const &path);

63
src/SwgContext.hxx Normal file
View File

@ -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
* <https://www.gnu.org/licenses/>.
*
* Contact luca0N! by e-mail: <luca0n [at] luca0n [dot] com>.
*/
#pragma once
#include <string>
#include <list>
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<Blog*> 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;
};*/

27
src/SwgRuntime.cxx Normal file
View File

@ -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
* <https://www.gnu.org/licenses/>.
*
* Contact luca0N! by e-mail: <luca0n [at] luca0n [dot] com>.
*/
#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;
}

27
src/SwgRuntime.hxx Normal file
View File

@ -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
* <https://www.gnu.org/licenses/>.
*
* Contact luca0N! by e-mail: <luca0n [at] luca0n [dot] com>.
*/
#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);

238
src/WebsiteBuilder.cxx Normal file
View File

@ -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
* <https://www.gnu.org/licenses/>.
*
* Contact luca0N! by e-mail: <luca0n [at] luca0n [dot] com>.
*/
#include <iostream>
#include <cstring>
#include <string>
#include <list>
#include <regex>
#include <filesystem>
#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<std::string> 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("<!--\\[_SWG: \\$CONTENT\\]-->");
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<std::string> 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();
}

27
src/WebsiteBuilder.hxx Normal file
View File

@ -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
* <https://www.gnu.org/licenses/>.
*
* Contact luca0N! by e-mail: <luca0n [at] luca0n [dot] com>.
*/
#pragma once
#include "SwgContext.hxx"
void build_website(SwgContext &ctx, std::string const &path);

84
src/main.cxx Normal file
View File

@ -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
* <https://www.gnu.org/licenses/>.
*
* Contact luca0N! by e-mail: <luca0n [at] luca0n [dot] com>.
*/
#include <iostream>
#include <cstring>
#include <string>
#include <list>
#include <regex>
#include <filesystem>
#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;
}