recettes/build.js

326 lines
8 KiB
JavaScript

var metalsmith = require('metalsmith')
var layouts = require('metalsmith-layouts')
var markdown = require('metalsmith-markdown')
var collections = require('metalsmith-collections')
var pagination = require('metalsmith-pagination')
var paths = require('metalsmith-paths')
var filemetadata = require('metalsmith-filemetadata')
var matters = require('metalsmith-matters')
var fs = require('fs');
var moment = require('moment');
var handlebars = require('handlebars');
var hlayouts = require('handlebars-layouts');
handlebars.registerHelper(hlayouts(handlebars));
handlebars.registerPartial('base', fs.readFileSync('templates/base.hbs', 'utf8'));
handlebars.registerPartial('index', fs.readFileSync('templates/index.hbs', 'utf8'));
handlebars.registerHelper('formatDate', function(date) {
return moment(new Date(date)).format('MMMM D, YYYY HH:mm:ss');
});
handlebars.registerHelper('formatTimestamp', function(date) {
return moment(date, 'X').format('MMMM D, YYYY HH:mm:ss');
});
function compareWith(v1, v2, operator) {
var itm = false;
switch (operator) {
case '==':
itm = (v1 == v2);
break;
case '!=':
itm = (v1 != v2);
break;
case '===':
itm = (v1 === v2);
break;
case '<':
itm = (v1 < v2);
break;
case '<=':
itm = (v1 <= v2);
break;
case '>':
itm = (v1 > v2);
break;
case '>=':
itm = (v1 >= v2);
break;
}
return itm;
}
handlebars.registerHelper('eachSorted', function(context, options) {
var ret = '';
if (context == undefined) {
return ret;
}
var keyList = Object.keys(context);
var sortFun = function(a,b) {
a = context[a];
b = context[b];
if (!a && !b) {
return 0;
}
if (!a) {
return -1;
}
if (!b) {
return 1;
}
a = a.data.title;
b = b.data.title;
if (b > a) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
};
keyList.sort(sortFun).forEach(function(key) {
if (key !== 'metadata') {
ret += options.fn(context[key]);
}
});
return ret;
})
handlebars.registerHelper('eachCond', function(context, member, operator, cond, options) {
var tot = '';
for (var i = 0; i < context.length; i++) {
var itm = false;
var v1 = context[i][member];
if (compareWith(v1, cond, operator)) {
tot += options.fn(context[i]);
}
}
return tot;
});
handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
if (compareWith(v1, v2, operator)) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
metalsmith(__dirname)
.source('recettes')
.metadata(require('./config/metadata'))
.frontmatter(false)
.use(matters(require('./config/matters')))
.use(filemetadata(require('./config/filemetadata')))
.use(addCategory())
.use(createCategories())
.use(collections(require('./config/collections')))
.use(markdown(require('./config/markdown')))
.use(pagination(require('./config/pagination')))
.use(paths(require('./config/paths')))
.use(layouts(require('./config/layouts')))
.use(copyVendor())
.use(epubGen())
.destination('build')
.build(function (err) {
if (err) {
throw err
}
})
function epubGen() {
var fs = require('fs');
var epubGenerator = require('epub-generator');
return function(files, metalsmith, done) {
var epubStream = epubGenerator({
title: metalsmith.metadata().site.title,
author: metalsmith.metadata().site.authors,
language: metalsmith.metadata().site.language
});
for (var f in files) {
if (files[f].type == 'recette') {
epubStream.add(f, files[f].contents, {
title: files[f].data.title,
toc: true
});
} else if (files[f].type == 'style') {
epubStream.add(f, files[f].contents, {
toc: false
});
}
}
epubStream.end()
.pipe( fs.createWriteStream('basic.epub') )
.on('error', function(err){
console.trace(err);
});
return done();
}
}
var recetteSortByTitle = function(a, b) {
a = a.data.title;
b = b.data.title;
if (!a && !b) {
return 0;
}
if (!a) {
return -1;
}
if (!b) {
return 1;
}
if (b > a) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
function createCategories() {
return function(files, metalsmith, done) {
var tagList = {};
for (var fileName in files) {
var data = files[fileName];
if (!data) {
continue;
}
var tagsData = data.category;
if (!tagsData) {
continue;
}
if (typeof tagsData === 'string') {
tagsData = tagsData.split(',');
}
data.category = [];
tagsData.forEach(function(rawTag) {
var tag = String(rawTag).trim();
data.category.push(tag);
if (!tagList[tag]) {
tagList[tag] = [];
}
tagList[tag].push(fileName);
});
}
var metadata = metalsmith.metadata();
metadata.tags = metadata.tags || {};
for (var tag in tagList) {
var posts = tagList[tag].map(function(fileName) {
return files[fileName];
}).sort(recetteSortByTitle);
var tagPage = files[tag + '/index.md'];
tagPage.tag = tag;
tagPage.posts = posts;
tagPage.title = tagPage.data.title;
posts.forEach(function(post) {
post.categoryPage = tagPage;
});
metadata['tags'][tag] = tagPage;
}
tagList = {};
return done();
}
}
function addCategory() {
return function(files, metalsmith, done) {
for (var f in files) {
if (f.indexOf('.md') > 0 && f.indexOf('index.md') < 0) {
var idx = f.indexOf('/');
var cat = f.substring(0, idx);
files[f].category = cat;
files[f].title = files[f].data.title;
}
}
return done();
}
}
function debugCollection() {
return function(files, metalsmith, done) {
console.log(files);
for (var i in files) {
console.log(i + ' -> ' + ' (' + files[i].collection + ')');
console.log(files[i]);
}
return done();
}
}
function debugMeta(metaname) {
return function(files, metalsmith, done) {
if (metaname !== undefined) {
console.log(metalsmith.metadata()[metaname]);
} else {
console.log(metalsmith.metadata());
}
return done();
}
}
function copyVendor() {
return function(files, metalsmith, done){
var styleFiles = fs.readdirSync('styles');
for (var i = 0; i < styleFiles.length; i++) {
var stylePath = 'styles/' + styleFiles[i];
files[stylePath] = {
contents: fs.readFileSync(stylePath),
type: 'style'
};
}
var fontFiles = fs.readdirSync('fonts');
for (var i = 0; i < fontFiles.length; i++) {
var fontPath = 'fonts/' + fontFiles[i];
files[fontPath] = {
contents: fs.readFileSync(fontPath),
type: 'font'
};
}
return done();
};
}