Add Article namespace for metadata parsing
Added a new namespace used for parsing article metadata embedded in article Markdown files, and updated the Makefile accordingly.
This commit is contained in:
parent
7dc67e3563
commit
0624e9bb60
9
Makefile
9
Makefile
|
@ -24,8 +24,8 @@ CXXFLAGS=-Wall -Wextra -g -O0 -std=c++17
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
$(PROGRAM_NAME): build/ build/obj/ build/obj/main.o build/obj/ConfigUtils.o build/obj/WebsiteBuilder.o build/obj/SwgRuntime.o build/obj/MarkdownParser.o
|
$(PROGRAM_NAME): build/ build/obj/ build/obj/main.o build/obj/ConfigUtils.o build/obj/WebsiteBuilder.o build/obj/SwgRuntime.o build/obj/MarkdownParser.o build/obj/Article.o
|
||||||
$(CXXC) -o $(PROGRAM_NAME) build/obj/main.o build/obj/ConfigUtils.o build/obj/WebsiteBuilder.o build/obj/SwgRuntime.o build/obj/MarkdownParser.o
|
$(CXXC) -o $(PROGRAM_NAME) build/obj/main.o build/obj/ConfigUtils.o build/obj/WebsiteBuilder.o build/obj/SwgRuntime.o build/obj/MarkdownParser.o build/obj/Article.o
|
||||||
|
|
||||||
build/obj/main.o: src/main.cxx src/ConfigUtils.hxx src/SwgContext.hxx src/WebsiteBuilder.hxx src/Common.hxx
|
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
|
$(CXXC) $(CXXFLAGS) -o build/obj/main.o -c src/main.cxx
|
||||||
|
@ -33,7 +33,7 @@ build/obj/main.o: src/main.cxx src/ConfigUtils.hxx src/SwgContext.hxx src/Websit
|
||||||
build/obj/ConfigUtils.o: src/ConfigUtils.cxx src/SwgContext.hxx src/Common.hxx
|
build/obj/ConfigUtils.o: src/ConfigUtils.cxx src/SwgContext.hxx src/Common.hxx
|
||||||
$(CXXC) $(CXXFLAGS) -o build/obj/ConfigUtils.o -c src/ConfigUtils.cxx
|
$(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 src/MarkdownParser.hxx
|
build/obj/WebsiteBuilder.o: src/WebsiteBuilder.hxx src/WebsiteBuilder.cxx src/SwgRuntime.hxx src/Common.hxx src/MarkdownParser.hxx src/Article.hxx
|
||||||
$(CXXC) $(CXXFLAGS) -o build/obj/WebsiteBuilder.o -c src/WebsiteBuilder.cxx
|
$(CXXC) $(CXXFLAGS) -o build/obj/WebsiteBuilder.o -c src/WebsiteBuilder.cxx
|
||||||
|
|
||||||
build/obj/SwgRuntime.o: src/SwgRuntime.hxx src/SwgRuntime.cxx
|
build/obj/SwgRuntime.o: src/SwgRuntime.hxx src/SwgRuntime.cxx
|
||||||
|
@ -42,6 +42,9 @@ build/obj/SwgRuntime.o: src/SwgRuntime.hxx src/SwgRuntime.cxx
|
||||||
build/obj/MarkdownParser.o: src/MarkdownParser.hxx src/MarkdownParser.cxx
|
build/obj/MarkdownParser.o: src/MarkdownParser.hxx src/MarkdownParser.cxx
|
||||||
$(CXXC) $(CXXFLAGS) -o build/obj/MarkdownParser.o -c src/MarkdownParser.cxx
|
$(CXXC) $(CXXFLAGS) -o build/obj/MarkdownParser.o -c src/MarkdownParser.cxx
|
||||||
|
|
||||||
|
build/obj/Article.o: src/Article.hxx src/Article.cxx
|
||||||
|
$(CXXC) $(CXXFLAGS) -o build/obj/Article.o -c src/Article.cxx
|
||||||
|
|
||||||
build/:
|
build/:
|
||||||
mkdir -p build/
|
mkdir -p build/
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* 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 "Article.hxx"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Common.hxx"
|
||||||
|
|
||||||
|
enum IterationStage {
|
||||||
|
CHECKING_TITLE,
|
||||||
|
READING_TITLE,
|
||||||
|
CHECKING
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Article {
|
||||||
|
/*
|
||||||
|
* FIXME: The article metadata declaration uses the same INI format as
|
||||||
|
* swg.cfg. Since they use the exact same format, we could unify the .cfg
|
||||||
|
* parsing into one function.
|
||||||
|
*/
|
||||||
|
void get_metadata(std::string const &path, Metadata *m) {
|
||||||
|
memset(m, 0, sizeof(Metadata));
|
||||||
|
FILE *a = fopen(path.c_str(), "r");
|
||||||
|
|
||||||
|
int buflen = 16;
|
||||||
|
char buf[buflen];
|
||||||
|
|
||||||
|
const char *det_article = "<!--SwgArticle";
|
||||||
|
size_t det_article_pos = 0;
|
||||||
|
bool reading_metadata = false,
|
||||||
|
done = false,
|
||||||
|
skip = false;
|
||||||
|
|
||||||
|
std::list<std::string> cfg_lines = { "" };
|
||||||
|
|
||||||
|
while (fgets(buf, buflen, a) != NULL) {
|
||||||
|
// Ignore blank lines or lines starting with a comment.
|
||||||
|
if (buf[0] == '\n' || buf[0] == '#') continue;
|
||||||
|
int eol = -1;
|
||||||
|
for (int c = 0; c < buflen; c++) {
|
||||||
|
// Check if this loop has already done what it's supposed to do by checking if the title has been set.
|
||||||
|
if (done || buf[c] == '\0') break;
|
||||||
|
if (!reading_metadata) {
|
||||||
|
// FIXME: This code will not work if buflen < strlen(det_article).
|
||||||
|
if (buf[c] == det_article[det_article_pos]) {
|
||||||
|
det_article_pos++;
|
||||||
|
} else {
|
||||||
|
// TODO: Instead of exiting with an
|
||||||
|
// error code, prompt the end user
|
||||||
|
// whether the build should continue
|
||||||
|
// (while ignoring this article) or
|
||||||
|
// stop.
|
||||||
|
std::cerr << "error: invalid article: " << path << "\n";
|
||||||
|
exit(RETURN_FAILED_UNKNOWN_ERROR);
|
||||||
|
}
|
||||||
|
if (det_article_pos == strlen(det_article)) {
|
||||||
|
reading_metadata = true;
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check end of HTML comment
|
||||||
|
if (buf[c] == '-' &&
|
||||||
|
buf[c+1] == '-' &&
|
||||||
|
buf[c+2] == '>') {
|
||||||
|
reading_metadata = false;
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (buf[c] == '\n')
|
||||||
|
eol = c;
|
||||||
|
}
|
||||||
|
if (skip) { skip = false; continue; }
|
||||||
|
if (done) break;
|
||||||
|
if (reading_metadata) {
|
||||||
|
if (eol > -1) {
|
||||||
|
buf[eol] = '\0';
|
||||||
|
*(--cfg_lines.end()) += buf;
|
||||||
|
cfg_lines.insert(cfg_lines.end(), "");
|
||||||
|
} else
|
||||||
|
*(--cfg_lines.end()) += buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool reading_article_metadata = false;
|
||||||
|
|
||||||
|
for (std::string const &line : cfg_lines) {
|
||||||
|
std::cout << "[!] Line: " << line << "\n";
|
||||||
|
// Check namespace
|
||||||
|
if (reading_article_metadata) {
|
||||||
|
std::string k_title = "Title=",
|
||||||
|
k_authors = "Authors=",
|
||||||
|
k_published = "Published=";
|
||||||
|
if (line.find(k_title) == 0)
|
||||||
|
strncpy(m->title, line.substr(k_title.length()).c_str(), sizeof(m->title));
|
||||||
|
else if (line.find(k_authors) == 0)
|
||||||
|
strncpy(m->authors, line.substr(k_authors.length()).c_str(), sizeof(m->authors));
|
||||||
|
else if (line.find(k_published) == 0)
|
||||||
|
m->publish_ts = atoi(line.substr(k_published.length()).c_str());
|
||||||
|
else
|
||||||
|
std::cerr << "warning: ignoring unknown key/value due to unknown key: " << line << std::endl;
|
||||||
|
} else if (line[0] == '[') {
|
||||||
|
if (line == "[ArticleMetadata]") {
|
||||||
|
reading_article_metadata = true;
|
||||||
|
} else {
|
||||||
|
std::cerr << "error: article properties has unknown namespace: " << line << std::endl;
|
||||||
|
exit(RETURN_FAILED_CONFIG_INVALID_SYNTAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
namespace Article {
|
||||||
|
struct Metadata {
|
||||||
|
char title[128];
|
||||||
|
char authors[128]; // Author (or authors) for this article
|
||||||
|
|
||||||
|
// Epoch timestamps
|
||||||
|
long original_ts; // Original article timestamp (for "Originally written on [...]")
|
||||||
|
long publish_ts; // (for "Published on [...]")
|
||||||
|
long update_ts; // (for "Last updated on [...]")
|
||||||
|
|
||||||
|
// Article flags
|
||||||
|
bool partially_obsoleted,
|
||||||
|
obsoleted,
|
||||||
|
mature_content;
|
||||||
|
|
||||||
|
char partially_obsoleted_reason[256],
|
||||||
|
obsoleted_reason[256],
|
||||||
|
obsoletion_followup_article[128],
|
||||||
|
|
||||||
|
mature_content_reason[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
void get_metadata(std::string const &path, Metadata *m);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue