#include #include #include #include #include #include #include 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; std::string body; }; 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(file)), std::istreambuf_iterator()); 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; } cfg.frontmatter.body = content.substr(second_fence + 3); } return cfg; } std::string markdown_processing(const std::string& md) { char *raw = cmark_markdown_to_html(md.c_str(), md.size(),0); std::string html(raw); free(raw); return html; } 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.date << 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; std::cout << "title body: " << markdown_processing(front.frontmatter.body) << std::endl; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; return 1; } return 0; }