motyl

Opinionated blog-aware static site generator written in Ruby
Log | Files | Refs | README | LICENSE

commit acbe586fe2b481f067fc8988035ae38bad76e2b7
Author: Frederic Cambus <fred@statdns.com>
Date:   Thu, 25 Feb 2016 22:51:23 +0100

Initial commit

Diffstat:
ALICENSE | 28++++++++++++++++++++++++++++
Amotyl.lua | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 159 insertions(+), 0 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2016, Frederic Cambus +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Motyl nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/motyl.lua b/motyl.lua @@ -0,0 +1,131 @@ +#!/usr/bin/env lua +--[[ +############################################################################### +# # +# Motyl # +# Copyright (c) 2016, Frederic Cambus # +# http://www.cambus.net/motyl/ # +# # +# Created: 2016-02-16 # +# Last Updated: 2016-02-25 # +# # +# Motyl is released under the BSD 3-Clause license. # +# See LICENSE file for details. # +# # +############################################################################### +]]-- + +local cjson = require "cjson" +local lfs = require "lfs" +local lustache = require "lustache" +local markdown = require "markdown" + +local function readFile(path) + local file = io.open(path, "rb") + + local content = file:read "*all" + file:close() + + return content +end + +local function writeFile(path, data) + local file = io.open(path, "wb") + + file:write(data) + file:close() +end + +local function loadJSON(path) + return cjson.decode(readFile(path)) +end + +local function loadMD(path) + return markdown(readFile(path)) +end + +local function sortDates(a,b) + return a.date > b.date +end + +-- Loading configuration +local data = {} +data.site = loadJSON("config.json") +data.site.datetime = os.date("%c") +data.site.year = os.date('%Y') + +-- Loading templates +local templates = { + header = readFile("templates/header.mustache"), + archives = readFile("templates/archives.mustache"), + pages = readFile("templates/page.mustache"), + posts = readFile("templates/post.mustache"), + footer = readFile("templates/footer.mustache") +} + +data.site.posts = {} +data.site.categories = {} + +local function render(directory) + for file in lfs.dir(directory) do + if file ~= "." and file ~= ".." then + extension = file:match "[^.]+$" + + if extension == "md" then + path = file:match "(.*).md$" + print("Rendering : " .. file) + data.page = loadJSON(directory .. "/" .. path .. ".json") + data.page.content = loadMD(directory .. "/" .. path .. ".md") + data.page.url = path .. "/" + + if directory == "posts" then + table.insert(data.site.posts, data.page) + + data.page.categoryDisplay = {} + + -- Populate category table + for i, category in ipairs(data.page.categories) do + if not data.site.categories[category] then + data.site.categories[category] = {} + end + + table.insert(data.site.categories[category], data.page) + table.insert(data.page.categoryDisplay, { category = category, url = data.site.categoryMap[category]}) + end + end + + output = lustache:render(templates[directory], data, templates) + + lfs.mkdir(data.site.destination .. path) + writeFile(data.site.destination .. path .. "/index.html", output) + end + end + end +end + +-- Render posts and pages +lfs.mkdir(data.site.destination) + +render("posts") +render("pages") + +table.sort(data.site.posts, sortDates) + +-- Archives +data.page.title = "Archives" +lfs.mkdir(data.site.destination .. "archives") +output = lustache:render(templates.archives, data, templates) +writeFile(data.site.destination .. "archives/index.html", output) + +-- Categories +lfs.mkdir(data.site.destination .. "categories") + +for category in pairs(data.site.categories) do + table.sort(data.site.categories[category], sortDates) + data.page.title = category + data.site.posts = data.site.categories[category] + output = lustache:render(templates.archives, data, templates) + + lfs.mkdir(data.site.destination .. "categories/" .. data.site.categoryMap[category]) + writeFile(data.site.destination .. "categories/" .. data.site.categoryMap[category] .. "/index.html", output) +end