Browse Source

fix templating logic

master
alistair 3 years ago
parent
commit
1c556cc6ec
  1. 2
      darkhttpd.c
  2. 48
      default-templates/html.template
  3. 27
      default-templates/style.css
  4. 244
      default-templates/style2.css
  5. 69
      default-templates/template.html
  6. 85
      main.cpp
  7. 5
      templater.hpp

2
darkhttpd.c

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
/* darkhttpd - a simple, single-threaded, static content webserver.
* https://unix4lyfe.org/darkhttpd/
* Copyright (c) 2003-2021 Emil Mikulic <emikulic@gmail.com>

48
default-templates/html.template

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="$lang$" xml:lang="$lang$"$if(dir)$ dir="$dir$"$endif$>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
{{ ifdef:title:<title>{{ :title }}</title> }}
<link rel="stylesheet" type="text/css" href="{{:url}}/style.css">
</head>
<body>
<div class="grid-container">
<div class=header_group>
</div>
<div class=menu_group>
<ul>
<li class=menu_item><a href="{{:url}}">home</a></li>
</ul>
</div>
<div class=main_page>
<header>
{{ifdef:title:<h1 class="title">{{ :title }}</h1>}}
{{ifdef:date:<p class="date">Published {{ :date }}</p>}}
</header>
{{ :body}}
</hr>
</div>
</div>
</div>
</body>
</html>

27
default-templates/style.css

@ -7,9 +7,6 @@ @@ -7,9 +7,6 @@
--borders: #bbb;
}
code {
white-space: pre-wrap;
background: var(--secondary-bg);
@ -98,6 +95,19 @@ body .main_page p { @@ -98,6 +95,19 @@ body .main_page p {
margin-bottom:0.3em;
}
.nosmoothing {
width:100%;
image-rendering: optimizeSpeed; /* STOP SMOOTHING, GIVE ME SPEED */
image-rendering: -moz-crisp-edges; /* Firefox */
image-rendering: -o-crisp-edges; /* Opera */
image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
image-rendering: pixelated; /* Chrome */
image-rendering: optimize-contrast; /* CSS3 Proposed */
-ms-interpolation-mode: nearest-neighbor; /* IE8+ */
}
img {
margin: auto;
max-width: 90%;
@ -152,6 +162,7 @@ q { @@ -152,6 +162,7 @@ q {
.menu_group {
grid-area: menu_group;
height:100%;
position:fixed;
}
@ -172,7 +183,6 @@ q { @@ -172,7 +183,6 @@ q {
justify-content: space-between;
}
@media (max-width: 1200px) {
.grid-container {
display: grid;
@ -201,9 +211,6 @@ q { @@ -201,9 +211,6 @@ q {
}
blockquote {
border-left: var(--borders);
border-left-style: solid;
@ -264,7 +271,6 @@ td { @@ -264,7 +271,6 @@ td {
}
.microblog_date {
font-size: 0.7em;
text-align: right;
@ -275,8 +281,9 @@ td { @@ -275,8 +281,9 @@ td {
}
.microblog_post {
background: var(--secondary-bg);
border-radius: 0.4em;
padding: 0.5em;
margin-top:0.6em;
margin-bottom:0.6em;
margin-top:0.1em;
margin-bottom:0.1em;
}

244
default-templates/style2.css

@ -1,244 +0,0 @@ @@ -1,244 +0,0 @@
code {
white-space: pre-wrap;
background: #eee;
border-color: #eee;
border-radius: 6px;
border-style: solid;
border-left-width: 4px;
border-right-width: 4px;
border-top-width:1px;
border-bottom-width:1px;
}
div.sourceCode {
background: #eee;
border-radius: 7px;
}
pre code {
border-style: none;
background: none;
}
code {
font-family: 'Bitstream Vera Sans Mono', 'Monospace', monospace;
}
pre {
font-family: 'Bitstream Vera Sans Mono', 'Monospace', monospace;
background: #eee;
border-radius:6px;
padding: 0.7em;
}
span.smallcaps {
font-variant: small-caps;
} span.underline {
text-decoration: underline;
}
div.column {
display: inline-block;
vertical-align: top;
width: 50%;
}
dl {
padding-left:1.5em;
}
dl dt {
font-size:0.6em;
font-weight:200;
}
dl dd {
margin-bottom:0.7em;
margin-left:0px;
}
dl dd a {
color:black;
}
body {
font-family: 'Bitrstream Vera Sans', Helvetica Neue, Helvetica, sans-serif, sans;
font-size: 18px;
}
body .main_page p {
line-height:1.3em;
}
.main_page li {
margin-top:0.3em;
margin-bottom:0.3em;
}
img {
margin: auto;
max-width: 90%;
display: block;
}
dd {
margin-top: 5px;
margin-bottom: 7px;
}
h1 {
margin-bottom: 10px;
margin-top: 10px;
}
h1, h2, h3, h4, h5, h6 {
font-weight:400;
}
a {
text-decoration:none;
color: #0066cc;
}
div.main_page {
padding-top: 0;
}
hr {
border-style: solid;
color: #bbb;
border-width:0.1em;
}
pre.numberSource {
margin-left: 4;
}
q {
quotes: "“" "”" "‘" "’";
}
.grid-container {
display: grid;
grid-template-columns: 2fr 3fr 3fr 4fr;
grid-template-rows: 0.5fr repeat(0.5, 1fr);
gap: 1px 1px;
grid-template-areas: "header_group header_group header_group header_group" "menu_group main_page main_page table_of_contents" "menu_group main_page main_page table_of_contents";
}
.header_group { grid-area: header_group; }
.menu_group {
grid-area: menu_group;
position:fixed;
}
.table_of_contents {
grid-area: table_of_contents;
max-width: 100%;
}
.main_page {
grid-area: main_page;
max-width:100%;
}
.menu_item {
display:block;
padding:5px;
display: flex;
justify-content: space-between;
}
@media (max-width: 1200px) {
.grid-container {
display: grid;
gap: 1px 1px;
grid-template-areas: "header_group header_group header_group header_group" "menu_group menu_group menu_group menu_group " "table_of_contents table_of_contents table_of_contents table_of_contents" "main_page main_page main_page main_page";
padding-left:10px;
padding-right:10px;
max-width: 45em;
margin:auto;
}
.menu_item {
display:inline-block;
}
.menu_group {
position:inherit;
}
.menu_group ul {
padding:0;
}
}
blockquote {
border-left: #bbb;
border-left-style: solid;
border-left-width: 0.2em;
padding:0.6em;
padding-left:1em;
}
blockquote p {
margin:0px;
}
tr:nth-child(even) {background-color: #eee;}
table {
border-collapse: collapse;
display:block;
overflow:auto;
width:100%;
margin: 0, auto;
}
.header th {
text-align: left;
border-bottom-style:solid;
border-left:none;
border-right:none;
border-bottom-width:1px;
}
td {
padding-top:0.3em;
padding-bottom:0.3em;
padding-left: 0.7em;
padding-right:0.7em;
}
thead {
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: black;
line-height: 2em;
}
.microblog_date {
font-size: 0.7em;
text-align: right;
}
.microblog_post .microblog_content p {
margin-top: 0.1em;
}
.microblog_post {
background: var(--secondary-bg);
border-radius: 0.4em;
padding: 0.5em;
margin-top:0.1em;
margin-bottom:0.1em;
}

69
default-templates/template.html

@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="$lang$" xml:lang="$lang$"$if(dir)$ dir="$dir$"$endif$>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
{{ifdef:title:
<title>{{ :title }}</title>
}}
<!-- <link rel="stylesheet" type="text/css" href="${baseurl}/media/style.css"> -->
<style type="text/css">
{{ :css }}
</style>
<!-- <script
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
-->
<link rel="stylesheet"
href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
<!-- The loading of KaTeX is deferred to speed up page rendering -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
<!-- To automatically render math in text elements, include the auto-render extension: -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"
onload="renderMathInElement(document.body);"></script>
</head>
</head>
<body>
<div class="grid-container">
<div class=header_group>
</div>
<div class=menu_group>
<ul>
<li class=menu_item><a href="{{:url}}">home</a></li>
</ul>
</div>
<div class=main_page>
<header>
{{ifdef:title:
<h1 class="title">{{:title }}</h1>
}}
{{ifdef:date:
<p class="date">{{:date }}</p>
}}
</header>
{{ :body}}
</div>
</div>
</div>
</body>
</html>

85
main.cpp

@ -40,6 +40,8 @@ const std::string DEFAULT_IGNORE_FILES[] = {SITE_CONFIG_FNAME}; @@ -40,6 +40,8 @@ const std::string DEFAULT_IGNORE_FILES[] = {SITE_CONFIG_FNAME};
const std::string TEST_URL = "http://localhost:8000";
static volatile bool continue_running = true;
const std::string short_info("stgen3 prerelease from git.topsot.net (c) 2020-2021 Alistair Michael.");
using json = nlohmann::json;
namespace fs = std::filesystem;
@ -52,13 +54,7 @@ struct runtime_config { @@ -52,13 +54,7 @@ struct runtime_config {
runtime_config settings;
/*
std::string_view trim_whitespace(std::string_view s) {
int ff = s.find_first_not_of(" \n\t");
int ll = s.find_last_not_of(" \n\t");
return s.substr(ff, ll - ff + 1);
}
*/
/* Fork and exec a command given in args taking input from in and sending
@ -98,6 +94,7 @@ class builder { @@ -98,6 +94,7 @@ class builder {
std::map<std::string, std::string> default_templates;
std::map<std::string, std::string> properties;
templater *templr;
templater *textsub_templr;
std::map<fs::path, time_t> last_build;
@ -273,7 +270,7 @@ class builder { @@ -273,7 +270,7 @@ class builder {
dir_last_update_time = t;
}
} else {
spdlog::info("ba d date parse");
spdlog::info("bad date parse");
}
std::string ndate = reformat_date(article_properties.at("date"), article_properties);
@ -281,13 +278,10 @@ class builder { @@ -281,13 +278,10 @@ class builder {
}
if (!article_properties.count("notemplating")) {
templr->run_substitution_plugins(text, article_properties);
}
std::string default_template_name = "none";
////////////////// GET THE TEMPLATE READY //////////////////////
article_properties["body"] = parser.cut_frontmatter(text);
std::string default_template_name = "none";
/* Process body content */
if (ext == "html") {
@ -300,13 +294,10 @@ class builder { @@ -300,13 +294,10 @@ class builder {
if (ext == "md" || ext == "markdown") {
default_template_name = "html";
std::string html = parser.parse_to_html(text);
article_properties["body"] = html;
}
article_properties["original"] = article_properties["body"];
std::string new_page {};
/*
if (page_templates.count(default_template_name)) {
new_page = page_templates.at(default_template_name);
@ -329,12 +320,42 @@ class builder { @@ -329,12 +320,42 @@ class builder {
spdlog::warn("Template not found for: {}", entry.string());
}
/* write body into template */
// TEMPLATING ON THE TEMPLATE //
spdlog::info("article: properties: {}", json{article_properties}.dump(4));
templr->run_substitution_plugins(new_page, article_properties);
/////////////////////////////////////////////////////////////////
//////////////// RUN TEMPLATING ON CONTENT //////////////////////
if (!article_properties.count("notemplating")) {
templr->run_substitution_plugins(text, article_properties);
}
std::string ntext = parser.cut_frontmatter(text);
// article_properties["body"] = parser.cut_frontmatter(text);
if (ext == "md" || ext == "markdown") {
text = parser.parse_to_html(text);
}
/////////////////////////////////////////////////////////////////
article_properties["original"] = text;
/* write content into template */
std::map<std::string, std::string> sub_content_keys {{"body", text}};
textsub_templr->run_substitution_plugins(new_page, sub_content_keys);
article_properties["body"] = new_page;
notify_file_write(target);
compile_jobs[target] = {job_type::TEMPLATE, entry, std::map<std::string, std::string>(article_properties), article_last_update};
compile_jobs[target] = {job_type::WRITE_ARTICLE, entry, std::map<std::string, std::string>(article_properties), article_last_update};
continue;
}
@ -392,8 +413,8 @@ class builder { @@ -392,8 +413,8 @@ class builder {
std::string properties_json ((char *)default_templates_stgen_json,
default_templates_stgen_json_len);
std::string html_template((char *)default_templates_template_html,
default_templates_template_html_len);
std::string html_template((char *)default_templates_html_template,
default_templates_html_template_len);
/* PROPERTIES.JSON DEFAULT VALUES */
std::istringstream in (properties_json);
@ -425,8 +446,6 @@ class builder { @@ -425,8 +446,6 @@ class builder {
properties["css"] = css;
properties["current_file"] = "default_html_template";
templr->run_substitution_plugins(html_template, properties);
default_templates["html"]= html_template;
default_templates["css"] = css;
properties.erase("current_file");
@ -441,11 +460,12 @@ class builder { @@ -441,11 +460,12 @@ class builder {
templr = new templater({new variable_transclude_plugin{}, new file_index_plugin{{SITE_CONFIG_FNAME, "index.md", "html.template"}}, new ifdef_plugin{}, new ifndef_plugin{}, new file_transclude_plugin{}, new mmd_snippet_transclude_plugin{}},
{new rss_feed_plugin{}, new microblog_plugin{}});
textsub_templr = new templater({new variable_transclude_plugin{}}, {});
add_default_templates();
update_file_dates();
}
~builder() {delete templr;}
~builder() {delete templr; delete textsub_templr;}
bool get_confirmation(std::string message) {
if (settings.no_interactive) {
@ -496,17 +516,19 @@ class builder { @@ -496,17 +516,19 @@ class builder {
if (job_type::TEMPLATE & e.second.type) {
// reapply stg1 and stg2 templates
std::string page = e.second.properties.at("body");
e.second.properties.erase("body");
templr->run_substitution_plugins(page,
e.second.properties, compile_jobs);
e.second.properties["body"] = page;
}
if (job_type::MARKDOWN & e.second.type) {
// run markdown
// run markdown compiler and templating
}
}
for (auto &e: compile_jobs) {
if ((job_type::MARKDOWN | job_type::TEMPLATE) & e.second.type) {
if ((job_type::MARKDOWN | job_type::TEMPLATE | job_type::WRITE_ARTICLE) & e.second.type) {
write_file(e.first.string(), e.second.properties.at("body"));
last_build[e.second.src] = now;
}
@ -531,6 +553,8 @@ class builder { @@ -531,6 +553,8 @@ class builder {
if (get_confirmation("Config file exists, do you want to overwrite it?")) {
dump_stgen_json();
}
} else {
dump_stgen_json();
}
}
@ -568,6 +592,7 @@ class builder { @@ -568,6 +592,7 @@ class builder {
// stage 2 build
write_build(compile_jobs);
update_file_dates();
}
void update_file_dates() {
@ -650,15 +675,19 @@ class builder { @@ -650,15 +675,19 @@ class builder {
fs::create_directories(properties.at("source_root"));
const std::string template_dest = fs::path(properties.at("source_root")).append("html.template");
const std::string style_dest = fs::path(properties.at("source_root")).append("style.css");
const std::string doc_dest = fs::path(properties.at("source_root")).append("index.md");
const std::string documentation = std::string{(char *)default_templates_documentation_md, default_templates_documentation_md_len};
const std::string style = std::string{(char *)default_templates_style_css, default_templates_style_css_len};
// json propj = json{properties};
// std::string jtext = propj.dump(4);
write_file(template_dest, default_templates.at("html"));
write_file(doc_dest, documentation);
write_file(style_dest, style);
dump_stgen_json();
}
};
@ -776,6 +805,7 @@ void kill_childs(int sig) @@ -776,6 +805,7 @@ void kill_childs(int sig)
int main(int argc, char **argv) {
std::cout << short_info << std::endl;
// TODO:
//
// - force dirty everything option
@ -825,7 +855,6 @@ int main(int argc, char **argv) { @@ -825,7 +855,6 @@ int main(int argc, char **argv) {
server s {};
s.serve_now(cmd_options.at("publish_root"), "8000", "127.0.0.1");
spdlog::info("Rebuilding every 5 seconds.");
/* darkhttpd registers a signal handler so this just uses that as it is
* compiled in rather than fork and exec'd
*/

5
templater.hpp

@ -22,7 +22,8 @@ enum job_type { @@ -22,7 +22,8 @@ enum job_type {
MARKDOWN = 1 << 1,
TEMPLATE = 1 << 2,
DELETE_FILE = 1 << 3,
MAKE_DIR = 1 << 4
MAKE_DIR = 1 << 4,
WRITE_ARTICLE = 1 << 5
};
@ -975,7 +976,7 @@ class templater { @@ -975,7 +976,7 @@ class templater {
// break;
// spdlog::info("Substitution failed, {} in {}", nvocation, properties.at("current_file"));
} else if (properties.count("notemplating") || !subst.recurse) {
} else if (!subst.recurse) {
// do not recurse into substituted content
next += subst.num;
}

Loading…
Cancel
Save