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(); }; }