UNPKG

techy

Version:

Flat CMS based on Gulp and AbsurdJS

192 lines (173 loc) 6.22 kB
var through2 = require('through2'); var gutil = require('gulp-util'); var path = require('path'); var glob = require('glob-expand'); var Page = require('./Page'); var PluginError = gutil.PluginError; var yamlFront = require('yaml-front-matter'); module.exports = function(api) { var extend = function() { var process = function(destination, source) { for (var key in source) { if (hasOwnProperty.call(source, key)) { destination[key] = source[key]; } } return destination; }; var result = arguments[0]; for(var i=1; i<arguments.length; i++) { result = process(result, arguments[i]); } return result; } var getPagePaths = function(file) { file = path.normalize(file); if(cache.pagePaths[file]) { return cache.pagePaths[file]; } var p = path.dirname(file.replace(path.normalize(api.config.src), '')), numOfSlashes = 0, root = './'; p = p.replace(/\\/g, '/'); if(p == '/') { numOfSlashes = 0; } else { var m = p.match(/\//g); var numOfSlashes = m ? m.length : 0; } for(var i=0; i<numOfSlashes; i++) { root += '../'; } var res = { root: root, self: p.substr(1), file: path.basename(file) }; res.url = res.self + '/' + res.file.replace('.md', '.html'); return cache.pagePaths[file] = res; } var getInfo = function() { var info = { pages: [] }; var process = function(mdFiles) { var processedFiles = []; for(var i=0; i<mdFiles.length; i++) { if(path.normalize(mdFiles[i].toString()).replace(/\\/g, '/').indexOf('/node_modules/') == -1) { processedFiles.push(mdFiles[i]); var yamlConfig = yamlFront.loadFront(fs.readFileSync(mdFiles[i]).toString('utf8')); var mdContent = yamlConfig.__content; var page = extend(Page(), api.config); page.set('root', api.root); page.set('rootTechy', api.rootTechy); page.set('theme', api.theme); page.set('themeDir', api.themeDir); page.set('techyFiles', techyFiles); page.set('paths', getPagePaths(mdFiles[i])); page.set('infoPass', true); applyYamlConfig(page, yamlConfig); page.parser(mdContent, true); info.pages.push(page); } else { // console.log('Skipped: ' + mdFiles[i]); } } return processedFiles; } if(infoFiles.length > 0) { process(infoFiles); } else { infoFiles = process(glob({}, [ api.config.src + '/**/*.md', '!' + api.config.src + '/node_modules/**/*.md', '!' + api.config.dest + '/**/*.md' ])); } return info; } var applyYamlConfig = function(page, config) { if(page && config) { for(var prop in config) { if(prop != '__content') { page.set(prop, config[prop]); } } } } var getYamlFront = function(file) { return yamlFront.loadFront(fs.readFileSync(file).toString('utf8')); } // collecting techy methods var techyFiles = [].concat( glob({}, [ api.rootTechy + '/api/**/*.techy.js', api.root + '/**/*.techy.js' ]) ); var infoFiles = [], info = {}, cache = { yaml: {}, pagePaths: {} }; var createPage = function() { var page = extend(Page(), api.config); page.set('root', api.root); page.set('rootTechy', api.rootTechy); page.set('theme', api.theme); page.set('themeDir', api.themeDir); page.set('techyFiles', techyFiles); page.set('info', info); return page; } var processFile = function(file, next, noSave, pageData) { if(!next) { next = function() {} }; var page = createPage(); page.set('paths', getPagePaths(file.path)); page.parseMarkdownFile = processFile; if(pageData) { for(var prop in pageData) { page.set(prop, pageData[prop]); } } var fileRoot = path.dirname(file.path), endFile = '', ext = file.path.split('.').pop().toLowerCase(); infoPass = false, noMarkdown = false, noLayout = false; if(ext == 'md') { endFile = path.basename(file.path).replace('.md', '.html'); } else { noMarkdown = noLayout = true; endFile = path.basename(file.path).replace('.' + ext, ''); } var yamlConfig = getYamlFront(file.path); applyYamlConfig(page, yamlConfig); var content = page.parser(yamlConfig.__content, infoPass, noMarkdown).build(noLayout); if(!noSave && page.get('noSave') !== true) { file.contents = new Buffer(content); file.path = fileRoot + '/' + endFile; this.push(file); return next(); } else { next(); return content; } } function transform (file, enc, next) { if(file.isNull()) { this.push(file); // pass along return next(); } if(path.normalize(file.path.toString()).replace(/\\/g, '/').indexOf('/node_modules/') >= 0) { this.push(file); // pass along return next(); } if(file.isStream()) { this.emit('error', new PluginError('page', 'Streaming not supported')); return next(); } processFile.apply(this, [file, next]); } return { gulp: function() { info = getInfo(); return through2.obj(transform); }, create: createPage } }