Initialise repository with basic restia blog SSG
This commit is contained in:
commit
1a3a8088db
13 changed files with 179 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.tup
|
||||||
|
*.skooma
|
0
Tupfile
Normal file
0
Tupfile
Normal file
0
Tupfile.ini
Normal file
0
Tupfile.ini
Normal file
1
Tuprules.tup
Normal file
1
Tuprules.tup
Normal file
|
@ -0,0 +1 @@
|
||||||
|
: foreach *.skooma.yue |> yue %f -o %o |> %B
|
4
build
Executable file
4
build
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
tup
|
||||||
|
rm -rf blog/*
|
||||||
|
lua build.lua --copy css --copy javascript --output blog
|
118
build.lua
Normal file
118
build.lua
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
local arrr = require 'arrr'
|
||||||
|
local restia = require 'restia'
|
||||||
|
local shapeshift = require 'shapeshift'
|
||||||
|
local yaml = require 'lyaml'
|
||||||
|
local cmark = require 'cmark'
|
||||||
|
|
||||||
|
local params do
|
||||||
|
local is = shapeshift.is
|
||||||
|
local parse = arrr {
|
||||||
|
{ "Output directory", "--output", "-o", 'directory' };
|
||||||
|
{ "Input directory", "--input", "-i", 'directory' };
|
||||||
|
{ "Copy directory", "--copy", "-c", 'directory', 'repeatable' };
|
||||||
|
{ "Delete everything first", "--delete", "-d" };
|
||||||
|
}
|
||||||
|
local validate = shapeshift.table {
|
||||||
|
output = shapeshift.default("output", is.string);
|
||||||
|
input = shapeshift.default(".", is.string);
|
||||||
|
copy = shapeshift.default({}, shapeshift.all{
|
||||||
|
is.table,
|
||||||
|
shapeshift.each(is.string)
|
||||||
|
});
|
||||||
|
delete = shapeshift.default(false, shapeshift.is.boolean);
|
||||||
|
}
|
||||||
|
params = select(2, assert(validate(parse{...})))
|
||||||
|
end
|
||||||
|
package.loaded.params = params
|
||||||
|
|
||||||
|
local config = restia.config.bind('config', {
|
||||||
|
(require 'restia.config.readfile');
|
||||||
|
(require 'restia.config.lua');
|
||||||
|
(require 'restia.config.yaml');
|
||||||
|
})
|
||||||
|
package.loaded.config = config
|
||||||
|
|
||||||
|
local templates = restia.config.bind('templates', {
|
||||||
|
(require 'restia.config.skooma');
|
||||||
|
})
|
||||||
|
package.loaded.templates = templates
|
||||||
|
|
||||||
|
local function read_post(file)
|
||||||
|
local content = io.open(file):read("*a")
|
||||||
|
local head, body = restia.utils.frontmatter(content)
|
||||||
|
return {
|
||||||
|
head = head and yaml.load(head) or {};
|
||||||
|
body = cmark.render_html(cmark.parse_document(body, #body, cmark.OPT_DEFAULT), cmark.OPT_DEFAULT);
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local posts = {}
|
||||||
|
package.loaded.posts = posts
|
||||||
|
|
||||||
|
local tree = {}
|
||||||
|
|
||||||
|
for i, path in ipairs(params.copy) do
|
||||||
|
restia.utils.deepinsert(tree, restia.utils.fs2tab(path), restia.utils.readdir(path))
|
||||||
|
end
|
||||||
|
|
||||||
|
local validate_head do
|
||||||
|
local is = shapeshift.is
|
||||||
|
validate_head = shapeshift.table {
|
||||||
|
__extra = 'keep';
|
||||||
|
title = is.string;
|
||||||
|
date = shapeshift.matches("%d%d%d%d%-%d%d%-%d%d");
|
||||||
|
file = is.string;
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function parsedate(date)
|
||||||
|
local year, month, day = date:match("(%d+)%-(%d+)%-(%d+)")
|
||||||
|
return os.time {
|
||||||
|
year = tonumber(year);
|
||||||
|
month = tonumber(month);
|
||||||
|
day = tonumber(day);
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Load Posts
|
||||||
|
for file in restia.utils.files(params.input, "%.md$") do
|
||||||
|
local post = read_post(file)
|
||||||
|
post.head.file = file
|
||||||
|
|
||||||
|
assert(validate_head(post.head))
|
||||||
|
|
||||||
|
post.head.timestamp = parsedate(post.head.date)
|
||||||
|
|
||||||
|
post.head.slug = post.head.title
|
||||||
|
:gsub(' ', '_')
|
||||||
|
:lower()
|
||||||
|
:gsub('[^a-z0-9-_]', '')
|
||||||
|
|
||||||
|
post.head.uri = string.format("/%s/%s.html", post.head.date:gsub("%-", "/"), post.head.slug)
|
||||||
|
post.path = restia.utils.fs2tab(post.head.uri)
|
||||||
|
|
||||||
|
table.insert(posts, post)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(posts, function(a, b)
|
||||||
|
return a.head.timestamp > b.head.timestamp
|
||||||
|
end)
|
||||||
|
|
||||||
|
local function render(name, ...)
|
||||||
|
return templates.main(templates[name], ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Render Posts
|
||||||
|
for idx, post in ipairs(posts) do
|
||||||
|
local body = restia.utils.deepconcat(render("post", post.body, post.head))
|
||||||
|
|
||||||
|
restia.utils.deepinsert(tree, post.path, body)
|
||||||
|
end
|
||||||
|
|
||||||
|
tree["index.html"] = render("index", posts)
|
||||||
|
|
||||||
|
if params.delete then
|
||||||
|
restia.utils.delete(params.output)
|
||||||
|
end
|
||||||
|
|
||||||
|
restia.utils.builddir(params.output, tree)
|
11
css/post.css
Normal file
11
css/post.css
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
body {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 60em 1fr;
|
||||||
|
gap: 2em;
|
||||||
|
}
|
||||||
|
nav {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
article {
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
3
css/reset.css
Normal file
3
css/reset.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
1
css/site.css
Normal file
1
css/site.css
Normal file
|
@ -0,0 +1 @@
|
||||||
|
@import url('reset.css');
|
1
templates/Tupfile
Normal file
1
templates/Tupfile
Normal file
|
@ -0,0 +1 @@
|
||||||
|
include_rules
|
6
templates/index.skooma.yue
Normal file
6
templates/index.skooma.yue
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import output from require 'params'
|
||||||
|
|
||||||
|
link = =>
|
||||||
|
a @title, href: "/"..output..@uri
|
||||||
|
|
||||||
|
(prefix) => ul [li link post.head, prefix for post in *@], title "Index"
|
15
templates/main.skooma.yue
Normal file
15
templates/main.skooma.yue
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import output from require 'params'
|
||||||
|
|
||||||
|
(...) =>
|
||||||
|
content, head_content = @(...)
|
||||||
|
return render.html(html {
|
||||||
|
lang: "english"
|
||||||
|
head {
|
||||||
|
link rel: "stylesheet", href: "/#{output}/css/site.css"
|
||||||
|
meta charset: "UTF-8"
|
||||||
|
head_content
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
content
|
||||||
|
}
|
||||||
|
})
|
17
templates/post.skooma.yue
Normal file
17
templates/post.skooma.yue
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import output from require 'params'
|
||||||
|
|
||||||
|
url = (path) -> "/"..output..path
|
||||||
|
|
||||||
|
(attributes) =>
|
||||||
|
{
|
||||||
|
nav {
|
||||||
|
ul {
|
||||||
|
li a "Index", href: url "/"
|
||||||
|
[li a post.head.title, href: url post.head.uri for post in *require("posts")]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
article { h1(attributes.title), @ }
|
||||||
|
}, {
|
||||||
|
title attributes.title
|
||||||
|
link rel: "stylesheet", href: "/#{output}/css/post.css"
|
||||||
|
}
|
Loading…
Reference in a new issue