blob: bffbe5f5ccd0fb17b074e68fbdc28557123ef802 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#include <iostream>
#include <string>
#include <string_view>
#include <toml++/toml.hpp>
#include <fstream>
#include <cassert>
using namespace std::string_literals;
struct MainConfig {
std::string title;
std::string url;
std::string author;
};
struct FrontmatterConfig {
std::string title;
std::string date;
std::string categories;
std::string tags;
bool draft;
};
struct Config {
MainConfig main;
FrontmatterConfig frontmatter;
};
Config
parse_config(const std::string& filepath)
{
toml::table tbl;
Config cfg;
try {
tbl = toml::parse_file(filepath);
} catch (const toml::parse_error& err) {
std::cerr << "parsing failed: " << err << std::endl;
throw;
}
if (auto* main = tbl["main"].as_table()) {
cfg.main.title = (*main)["title"].value_or("untitled's blog");
cfg.main.url = (*main)["url"].value_or("localhost");
cfg.main.author = (*main)["author"].value_or("linus");
}
return cfg;
}
Config
frontmatter(const std::string& filepath)
{
Config cfg;
std::ifstream file(filepath);
std::string content((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
const size_t first_fence = content.find("+++");
const size_t second_fence = (first_fence == std::string::npos)
? std::string::npos
: content.find("+++", first_fence + 3);
/* TIL: npos == no position */
if (first_fence != std::string::npos && second_fence != std::string::npos) {
std::string fm = content.substr(first_fence + 3,
second_fence - (first_fence+3));
try {
toml::parse_result result = toml::parse(fm);
const toml::table& tbl = result;
cfg.frontmatter.title = tbl["title"].value_or(""s);
cfg.frontmatter.date = tbl["date"].value_or(""s);
cfg.frontmatter.categories = tbl["categories"].value_or(""s);
cfg.frontmatter.tags = tbl["tags"].value_or(""s);
cfg.frontmatter.draft = tbl["draft"].value_or(true);
} catch(const toml::parse_error& err) {
std::cerr << "parsing failed: " << err << std::endl;
throw;
}
}
return cfg;
}
int main(int argc, char *argv[]) {
try {
Config my_config = parse_config("config.toml");
std::cout << "title name: " << my_config.main.title << std::endl;
std::cout << "url name: " << my_config.main.url << std::endl;
std::cout << "author: " << my_config.main.author << std::endl;
Config front = frontmatter(argv[1]);
std::cout << "title page: " << front.frontmatter.title << std::endl;
std::cout << "title date: " << front.frontmatter.title << std::endl;
std::cout << "title categories: " << front.frontmatter.categories << std::endl;
std::cout << "title tags: " << front.frontmatter.tags << std::endl;
std::cout << "title draft: " << front.frontmatter.draft << std::endl;
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return 1;
}
return 0;
}
|