Generate blog catalog
WebsiteBuilder now generates a blog catalog containing each article from every blog. Articles are sorted by published date and are grouped based on their month and year.
This commit is contained in:
parent
4753920f3d
commit
304ed3013f
|
@ -131,7 +131,7 @@ namespace Article {
|
||||||
fclose(a);
|
fclose(a);
|
||||||
}
|
}
|
||||||
bool Comparator::comp(Metadata *a, Metadata *b) {
|
bool Comparator::comp(Metadata *a, Metadata *b) {
|
||||||
return a->publish_ts < b->publish_ts;
|
return a->publish_ts > b->publish_ts;
|
||||||
}
|
}
|
||||||
bool Comparator::equiv(Metadata *a, Metadata *b) {
|
bool Comparator::equiv(Metadata *a, Metadata *b) {
|
||||||
return a->publish_ts == b->publish_ts;
|
return a->publish_ts == b->publish_ts;
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace Article {
|
||||||
struct Metadata {
|
struct Metadata {
|
||||||
char title[128];
|
char title[128];
|
||||||
char authors[128]; // Author (or authors) for this article
|
char authors[128]; // Author (or authors) for this article
|
||||||
|
char path[256]; // Path to this article
|
||||||
|
|
||||||
// Epoch timestamps
|
// Epoch timestamps
|
||||||
long original_ts; // Original article timestamp (for "Originally written on [...]")
|
long original_ts; // Original article timestamp (for "Originally written on [...]")
|
||||||
|
|
|
@ -153,7 +153,6 @@ void build_blog_structure(std::string const &path, std::string const &prefix, st
|
||||||
Article::get_metadata(a, articleMetadata);
|
Article::get_metadata(a, articleMetadata);
|
||||||
std::cout << "Parsed metadata for article \"" << articleMetadata->title << "\"\n\tPublished on "
|
std::cout << "Parsed metadata for article \"" << articleMetadata->title << "\"\n\tPublished on "
|
||||||
<< ctime(&(articleMetadata->publish_ts)) << "\n";
|
<< ctime(&(articleMetadata->publish_ts)) << "\n";
|
||||||
am.push_back(articleMetadata);
|
|
||||||
|
|
||||||
// TODO: This code could be optimized by removing directory
|
// TODO: This code could be optimized by removing directory
|
||||||
// checks for every single article. Instead, add
|
// checks for every single article. Instead, add
|
||||||
|
@ -162,18 +161,25 @@ void build_blog_structure(std::string const &path, std::string const &prefix, st
|
||||||
// directories later as needed.
|
// directories later as needed.
|
||||||
try {
|
try {
|
||||||
// Create directory for the year of this article if it doesn't exist.
|
// Create directory for the year of this article if it doesn't exist.
|
||||||
std::filesystem::path oad = obp; // Output Article Directory
|
std::filesystem::path oad = obp, // Output Article Directory
|
||||||
|
rap; // Relative Article Path
|
||||||
oad /= year;
|
oad /= year;
|
||||||
|
rap /= year;
|
||||||
if (!std::filesystem::exists(oad)) std::filesystem::create_directory(oad);
|
if (!std::filesystem::exists(oad)) std::filesystem::create_directory(oad);
|
||||||
|
|
||||||
// Do the same for the article month.
|
// Do the same for the article month.
|
||||||
oad /= month;
|
oad /= month;
|
||||||
|
rap /= month;
|
||||||
if (!std::filesystem::exists(oad)) std::filesystem::create_directory(oad);
|
if (!std::filesystem::exists(oad)) std::filesystem::create_directory(oad);
|
||||||
|
|
||||||
// Now create the article file.
|
// Now create the article file.
|
||||||
oad /= getFilename(a, false);
|
std::string new_article_filename = getFilename(a, false);
|
||||||
oad += ".html";
|
new_article_filename += ".html";
|
||||||
|
oad /= new_article_filename;
|
||||||
|
rap /= new_article_filename;
|
||||||
compile_markdown(path, a, oad);
|
compile_markdown(path, a, oad);
|
||||||
|
strncpy(articleMetadata->path, rap.c_str(), sizeof(articleMetadata->path));
|
||||||
|
am.push_back(articleMetadata);
|
||||||
} catch (std::filesystem::filesystem_error const &e) {
|
} catch (std::filesystem::filesystem_error const &e) {
|
||||||
std::cerr << "error: failed to create directory for an article from blog \""
|
std::cerr << "error: failed to create directory for an article from blog \""
|
||||||
<< blog->name << "\": " << e.what() << std::endl;
|
<< blog->name << "\": " << e.what() << std::endl;
|
||||||
|
@ -182,6 +188,47 @@ void build_blog_structure(std::string const &path, std::string const &prefix, st
|
||||||
}
|
}
|
||||||
// Sort am list.
|
// Sort am list.
|
||||||
am.sort(Article::Comparator::comp);
|
am.sort(Article::Comparator::comp);
|
||||||
|
// Generate blog catalog.
|
||||||
|
std::string blog_html_catalog = "<ul>",
|
||||||
|
last_date = "";
|
||||||
|
std::string hr_month[] = {
|
||||||
|
"January",
|
||||||
|
"February",
|
||||||
|
"March",
|
||||||
|
"April",
|
||||||
|
"May",
|
||||||
|
"June",
|
||||||
|
"July",
|
||||||
|
"August",
|
||||||
|
"September",
|
||||||
|
"October",
|
||||||
|
"November",
|
||||||
|
"December"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (Article::Metadata *m : am) {
|
||||||
|
struct tm *article_time = gmtime(&(m->publish_ts));
|
||||||
|
std::string hr_date = hr_month[article_time->tm_mon];
|
||||||
|
hr_date += " ";
|
||||||
|
hr_date += std::to_string(article_time->tm_year + 1900);
|
||||||
|
// Check if this article belongs to the same "month + year" group as
|
||||||
|
// the last article. If it doesn't, add a new group to the catalog.
|
||||||
|
if (hr_date != last_date) {
|
||||||
|
last_date = hr_date;
|
||||||
|
blog_html_catalog += "<span><b>";
|
||||||
|
blog_html_catalog += hr_date;
|
||||||
|
blog_html_catalog += "</b></span>";
|
||||||
|
}
|
||||||
|
|
||||||
|
blog_html_catalog += "<li><a href=\"./";
|
||||||
|
blog_html_catalog += m->path;
|
||||||
|
blog_html_catalog += "\">";
|
||||||
|
blog_html_catalog += m->title;
|
||||||
|
blog_html_catalog += "</a></li>";
|
||||||
|
// Free memory as it's no longer needed.
|
||||||
|
free(m);
|
||||||
|
}
|
||||||
|
blog_html_catalog += "</ul>";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue