stamd

Static Markdown Page Generator
git clone git://git.dimitrijedobrota.com/stamd.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

article.cpp (4576B)


0 #include <format>
1 #include <iterator>
2 #include <numeric>
3 #include <optional>
4 #include <string>
6 #include "article.hpp"
8 #include <hemplate/attribute.hpp>
9 #include <hemplate/classes.hpp>
11 #include "utility.hpp"
13 namespace stamd
14 {
16 std::optional<std::string> Article::get(const std::string& key) const
17 {
18 const auto itr = m_symbols.find(key);
19 if (itr == end(m_symbols)) {
20 // std::cerr << "Warning: getting invalid value for: " << key << std::endl;
21 return {};
22 }
23 return itr->second;
24 }
26 std::string Article::get_filename() const
27 {
28 return m_filename;
29 }
31 std::string Article::get_date() const
32 {
33 return get("date").value_or("0000-00-00");
34 }
36 std::string Article::get_title() const
37 {
38 return get("title").value_or(get_filename());
39 }
41 std::string Article::get_language() const
42 {
43 return get("language").value_or("en");
44 }
46 std::string Article::get_desciprtion() const
47 {
48 return get("description").value_or(m_options.description);
49 }
51 std::string Article::get_author() const
52 {
53 return get("author").value_or(m_options.author);
54 }
56 std::string Article::get_keywords() const
57 {
58 static const auto concat = [](const categories_t& categories)
59 {
60 if (categories.empty()) {
61 return std::string();
62 }
64 return std::accumulate(
65 std::next(std::begin(categories)),
66 std::end(categories),
67 *categories.begin(),
68 [](const auto& acc, const auto& str)
69 {
70 return acc + ", " + str;
71 }
72 );
73 };
75 return get("keywords").value_or(concat(m_categories));
76 }
78 hemplate::element Article::print_nav(const std::string& base)
79 {
80 using namespace hemplate::html; // NOLINT
82 return nav {
83 a {
84 {{"class", "back"}},
85 "&lt;-- back",
86 },
87 a {
88 {{"href", base}},
89 "index",
90 },
91 a {
92 {{"href", "/"}},
93 "home --&gt;",
94 },
95 };
96 }
98 hemplate::element Article::print_categories(const categories_t& categories)
99 {
100 using namespace hemplate::html; // NOLINT
102 return nav {
103 {{"class", "categories"}},
104 h3 {"Categories: "},
105 p {
106 transform(
107 categories,
108 [](const auto& category)
110 auto ctgry = category;
111 normalize(ctgry);
112 return aHref {
113 std::format("./{}.html", ctgry),
114 category,
115 };
117 ),
118 },
119 };
122 hemplate::element Article::write(const content_t& content) const
124 using namespace hemplate::html; // NOLINT
126 return element {
127 doctype {},
128 html {
129 {{"lang", get_language()}},
130 head {
131 title {get_title()},
133 metaUTF8 {},
134 metaName {"author", get_author()},
135 metaName {"description", get_desciprtion()},
136 metaName {"keywords", get_keywords()},
137 metaName {"viewport", "width=device-width, initial-scale=1"},
139 linkStylesheet {"/css/index.css"},
140 linkStylesheet {"/css/colors.css"},
142 element {
143 linkRss {"RSS feed", "/blog/rss.xml"},
144 linkAtom {"Atom feed", "/blog/atom.xml"},
145 },
147 // Icons
148 linkIcon {"32x32", "/img/favicon-32x32.png"},
149 linkIcon {"16x16", "/img/favicon-16x16.png"},
150 },
151 body {
152 input {{
153 {"type", "checkbox"},
154 {"id", "theme_switch"},
155 {"class", "theme_switch"},
156 }},
157 hemplate::html::div {
158 {{"id", "content"}},
159 m_nonav ? element{} : [&] {
160 return header {
161 print_nav(m_options.base_url + "blog"),
162 hr{},
163 };
164 }(),
165 main {
166 label {
167 {{"for", "theme_switch"}, {"class", "switch_label"},},
168 },
169 m_categories.empty() ? element {} : [&]() {
170 return print_categories(m_categories);
171 }(),
172 content(),
173 },
174 m_nonav ? element{} : [&] {
175 return footer {
176 hr{},
177 print_nav(m_options.base_url + "blog"),
178 };
179 }(),
180 },
181 script {{{"set", "/scripts/main.js"}}},
182 },
183 },
184 };
187 } // namespace stamd