diff --git a/.htaccess b/.htaccess index fe9da8ad..7fc24852 100644 --- a/.htaccess +++ b/.htaccess @@ -1,4 +1,2 @@ RewriteEngine On RewriteRule ^(?!htdocs/)(.*)$ htdocs/$1 [L] - -AddType application/rss+xml rss diff --git a/converter.js b/converter.js index 7fde1614..5684f474 100755 --- a/converter.js +++ b/converter.js @@ -6,12 +6,48 @@ var fs = require('fs-extra'); var pkg = JSON.parse(fs.readFileSync('./package.json')); -var toolshed = require('./lib/js-toolshed/src/js-toolshed'); var glob = require("glob"); var readline = require("readline"); var yamljs = require('yamljs'); +/** + * Convert given UTC string into Date object + * @param {String} dateString like '2015-11-06 13:21:00+02:00' + * @return {Date} [description] + */ +var DateSetFromIsoString = function (dateString) { + var dateValues = dateString.match(/^(\d+)\-(\d+)\-(\d+)(?:.(\d+):(\d+):(\d+)(?:(\+|\-)(\d+)\:(\d+))?)?/), i, that = new Date(); + if (dateValues) { + for (i = 0; i <= 9; i++) { + if (!dateValues[i]) { + switch (i) { + case 7: + dateValues[i] = (that.getTimezoneOffset() >= 0) ? '+' : '-'; + break; + case 8: + dateValues[i] = Math.abs(that.getTimezoneOffset()/60); + break; + default: + dateValues[i] = 0; + break; + } + } else if (i !== 7) { + dateValues[i] = parseInt(dateValues[i]); + } + } + that = new Date(Date.UTC( + (dateValues[3]), + (dateValues[2] - 1), + (dateValues[1]), + ((dateValues[7] === '+') ? dateValues[4] - dateValues[8] : dateValues[4] + dateValues[8]), + ((dateValues[7] === '+') ? dateValues[5] - dateValues[9] : dateValues[5] + dateValues[9]), + (dateValues[6]) + )); + return that; + } + throw "No valid ISO time string"; +}; var fileConvert = function(file, newFile) { var yaml = '', @@ -59,9 +95,6 @@ var fileConvert = function(file, newFile) { if (yaml.taxonomy.tag !== undefined) { markdown = 'Keywords: '+yaml.taxonomy.tag.join(', ')+" \n"+markdown; } - //markdown += "\n"+markdownConvert(markdown); - //markdown += "\n"+markdownConvert(markdown.replace(/\S+:[\s\S]+?\n\n/,'')); - //console.log(yamljs.parse(markdown.match(/\S+:[\s\S]+?\n\n/)[0])); fs.writeFile(newFile, markdown); console.log("Wrote "+newFile); }); diff --git a/gulpfile.js b/gulpfile.js index a387f471..72510a2f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -57,4 +57,4 @@ gulp.task('watch', function() { // Default Task gulp.task('default', ['jshint']); gulp.task('test', ['jshint','nodeunit']); -gulp.task('compile', shell.task(['npm run compile'])); +gulp.task('compile', shell.task(['npm run start'])); diff --git a/index.js b/index.js index 01fe5802..b4540704 100755 --- a/index.js +++ b/index.js @@ -4,85 +4,13 @@ var fs = require('fs-extra'); var pkg = JSON.parse(fs.readFileSync('./package.json')); var config = JSON.parse(fs.readFileSync('./user/config.json')); -var shell = require('shelljs'); -var glob = require("glob"); -var Mustache = require('mustache'); -var PostReader = require('./lib/post_reader'); +var Generator = require('./lib/generator'); -// Priming stuff -var itemTemplate = fs.readFileSync(pkg.directories.theme+'/item.html', 'utf8'); -var indexTemplate = fs.readFileSync(pkg.directories.theme+'/index.html', 'utf8'); -var rssTemplate = fs.readFileSync(pkg.directories.theme+'/rss.xml', 'utf8'); -var sitemapTemplate = fs.readFileSync(pkg.directories.theme+'/sitemap.xml', 'utf8'); -var index = require('./lib/index')(); -Mustache.parse(itemTemplate); -Mustache.parse(indexTemplate); -Mustache.parse(rssTemplate); -Mustache.parse(sitemapTemplate); - -// Read items -glob(pkg.directories.data + "/**/*.md", function (er, files) { - var i, finished = 0; - - PostReader.on('parsed', function (post) { - shell.mkdir('-p', pkg.directories.htdocs + '/' + post.meta.Url); - fs.writeFile(pkg.directories.htdocs + '/' + post.meta.Url + 'index.html', Mustache.render(itemTemplate, { - meta: post.meta, - content: post.html, - config: config - })); - console.log("Wrote " + post.meta.Url + "index.html"); - index.push(post); - finished ++; - if (finished === files.length) { - var pagedPosts = index.getPagedPosts(5), page, indexFilename; - - fs.writeFile(pkg.directories.htdocs + '/sitemap.json', JSON.stringify(index.getPosts())); - fs.writeFile(pkg.directories.htdocs + '/sitemap-pages.json', JSON.stringify(pagedPosts)); - console.log("Wrote sitemap.json"); - - fs.remove(pkg.directories.htdocs + '/index*', function (err) { - for (page = 0; page < pagedPosts.length; page ++) { - var curPageObj = index.getPageData(page, pagedPosts.length); - curPageObj.index = pagedPosts[page]; - curPageObj.config = config; - fs.writeFile(pkg.directories.htdocs + '/' + curPageObj.currentUrl, Mustache.render(indexTemplate, curPageObj)); - console.log("Wrote " + curPageObj.currentUrl); - } - }); - - fs.writeFile(pkg.directories.htdocs + '/posts.rss', Mustache.render(rssTemplate, { - index: index.getPosts(10), - config: config - })); - console.log("Wrote posts.rss"); - - fs.writeFile(pkg.directories.htdocs + '/sitemap.xml', Mustache.render(sitemapTemplate, { - index: index.getPosts(10), - config: config - })); - console.log("Wrote sitemap.xml"); - - var tags = index.getTags(); - Object.keys(tags).map(function (key) { - shell.mkdir('-p', pkg.directories.htdocs + '/tagged/' + tags[key].id); - tags[key].config = config; - fs.writeFile(pkg.directories.htdocs + '/tagged/' + tags[key].id + '/index.html', Mustache.render(indexTemplate, tags[key])); - console.log("Wrote tagged/" + tags[key].id + '/index.html'); - - }); - } - }); - - for (i = 0; i < files.length; i++) { - PostReader.parse(files[i]); - } +Generator.init(config, pkg); +Generator.on('articlesBuild', function (post) { + Generator.buildOtherPages(); + Generator.copyImages(); }); -glob(pkg.directories.data + "/**/*.{png,jpg,gif}", function (er, files) { - var i; - for (i = 0; i < files.length; i++) { - fs.copySync(files[i], files[i].replace(/^user\//, 'htdocs/')); - } -}); +Generator.buildArticles(); diff --git a/lib/generator.js b/lib/generator.js new file mode 100644 index 00000000..497c38b4 --- /dev/null +++ b/lib/generator.js @@ -0,0 +1,133 @@ +'use strict'; + +var EventEmitter = require( "events" ).EventEmitter; +var Mustache = require('mustache'); +var fs = require('fs-extra'); +var shell = require('shelljs'); +var glob = require("glob"); +var PostReader = require('./post_reader'); + +/** + * Generator used for creating the blog + * @constructor + */ +var Generator = new EventEmitter(); + +var config = {}, pkg = {}, templates; +var index = require('./index')(); + +/** + * [init description] + * @param {[type]} Cconfig [description] + * @param {[type]} Cpkg [description] + * @return {[type]} [description] + */ +Generator.init = function ( Cconfig, Cpkg ) { + config = Cconfig; + pkg = Cpkg; + templates = { + post: fs.readFileSync(pkg.directories.theme+'/post.html', 'utf8'), + index: fs.readFileSync(pkg.directories.theme+'/index.html', 'utf8'), + rss: fs.readFileSync(pkg.directories.theme+'/rss.xml', 'utf8'), + sitemap: fs.readFileSync(pkg.directories.theme+'/sitemap.xml', 'utf8') + }; + + Object.keys(templates).map(function (template) { + Mustache.parse(template); + }); +} + +/** + * [buildArticles description] + * @return {[type]} [description] + */ +Generator.buildArticles = function () { + glob(pkg.directories.data + "/**/*.md", function (er, files) { + var i, finished = 0; + + PostReader.on('parsed', function (post) { + shell.mkdir('-p', pkg.directories.htdocs + '/' + post.meta.Url); + fs.writeFile(pkg.directories.htdocs + '/' + post.meta.Url + 'index.html', Mustache.render(templates.post, { + meta: post.meta, + content: post.html, + config: config + })); + // console.log("Wrote " + post.meta.Url + "index.html"); + index.push(post); + finished ++; + if (finished === files.length) { + console.log("Wrote "+files.length+" articles"); + Generator.emit('articlesBuild', finished); + } + }); + + for (i = 0; i < files.length; i++) { + PostReader.parse(files[i]); + } + }); +}; + +/** + * [buildOtherPages description] + * @return {[type]} [description] + */ +Generator.buildOtherPages = function ( ) { + var pagedPosts = index.getPagedPosts(5), page, indexFilename; + + fs.writeFile(pkg.directories.htdocs + '/sitemap.json', JSON.stringify(index.getPosts()), function() { + console.log("Wrote sitemap.json"); + }); + + fs.remove(pkg.directories.htdocs + '/index*', function (err) { + for (page = 0; page < pagedPosts.length; page ++) { + var curPageObj = index.getPageData(page, pagedPosts.length); + curPageObj.index = pagedPosts[page]; + curPageObj.config = config; + fs.writeFile(pkg.directories.htdocs + '/' + curPageObj.currentUrl, Mustache.render(templates.index, curPageObj), function() { + console.log("Wrote index file"); + }); + } + }); + + fs.writeFile(pkg.directories.htdocs + '/posts.rss', Mustache.render(templates.rss, { + index: index.getPosts(10), + config: config + }), function () { + console.log("Wrote posts.rss"); + }); + + fs.writeFile(pkg.directories.htdocs + '/sitemap.xml', Mustache.render(templates.sitemap, { + index: index.getPosts(10), + config: config + }),function () { + console.log("Wrote sitemap.xml"); + }); + + var tags = index.getTags(); + fs.remove(pkg.directories.htdocs + '/tagged', function (err) { + Object.keys(tags).map(function (key) { + shell.mkdir('-p', pkg.directories.htdocs + '/tagged/' + tags[key].id); + tags[key].config = config; + fs.writeFile(pkg.directories.htdocs + '/tagged/' + tags[key].id + '/index.html', Mustache.render(templates.index, tags[key]), function() { + console.log("Wrote tagged/" + tags[key].id + '/index.html'); + }); + }); + }); +}; + +Generator.copyImages = function () { + glob(pkg.directories.data + "/**/*.{png,jpg,gif}", function (er, files) { + var i, copiedFiles = 0; + var copyEnd = function () { + copiedFiles ++; + if (copiedFiles === files.length) { + console.log("Copied "+copiedFiles+" images"); + } + }; + for (i = 0; i < files.length; i++) { + fs.copy(files[i], files[i].replace(/^user\//, 'htdocs/'), copyEnd); + } + }); +}; + +module.exports = Generator; diff --git a/lib/index.js b/lib/index.js index c9c82fbd..9e50dd92 100644 --- a/lib/index.js +++ b/lib/index.js @@ -59,11 +59,11 @@ var Index = function () { index.forEach(function(post){ if (post.meta.Tags) { post.meta.Tags.forEach(function(tag){ - if (tags[tag.title] === undefined) { - tags[tag.title] = tag; - tags[tag.title].index = []; + if (tags[tag.id] === undefined) { + tags[tag.id] = tag; + tags[tag.id].index = []; } - tags[tag.title].index.push(post); + tags[tag.id].index.push(post); }); } }); diff --git a/lib/js-toolshed/src/js-toolshed.js b/lib/js-toolshed/src/js-toolshed.js index 548ee5dd..f0f388d0 100644 --- a/lib/js-toolshed/src/js-toolshed.js +++ b/lib/js-toolshed/src/js-toolshed.js @@ -156,42 +156,3 @@ return this; }; }()); - -/** - * Convert given UTC string into Date object - * @param {String} dateString like '2015-11-06 13:21:00+02:00' - * @return {Date} [description] - */ -var DateSetFromIsoString = function (dateString) { - 'use strict'; - var dateValues = dateString.match(/^(\d+)\-(\d+)\-(\d+)(?:.(\d+):(\d+):(\d+)(?:(\+|\-)(\d+)\:(\d+))?)?/), i, that = new Date(); - if (dateValues) { - for (i = 0; i <= 9; i++) { - if (!dateValues[i]) { - switch (i) { - case 7: - dateValues[i] = (that.getTimezoneOffset() >= 0) ? '+' : '-'; - break; - case 8: - dateValues[i] = Math.abs(that.getTimezoneOffset()/60); - break; - default: - dateValues[i] = 0; - break; - } - } else if (i !== 7) { - dateValues[i] = parseInt(dateValues[i]); - } - } - that = new Date(Date.UTC( - (dateValues[3]), - (dateValues[2] - 1), - (dateValues[1]), - ((dateValues[7] === '+') ? dateValues[4] - dateValues[8] : dateValues[4] + dateValues[8]), - ((dateValues[7] === '+') ? dateValues[5] - dateValues[9] : dateValues[5] + dateValues[9]), - (dateValues[6]) - )); - return that; - } - throw "No valid ISO time string"; -}; diff --git a/lib/post.js b/lib/post.js index 926e8c8f..3289d4d0 100644 --- a/lib/post.js +++ b/lib/post.js @@ -67,6 +67,7 @@ var Post = function (markdown, meta) { if (meta.Date !== undefined) { meta.localeDate = dateFormat(meta.Date,'dd.mm.yyyy'); meta.isoDate = dateFormat(meta.Date,'isoDateTime'); + meta.rfcDate = dateFormat(meta.Date,'ddd, dd mmm yyyy hh:MM:ss o'); // Wed, 02 Oct 2002 15:00:00 +0200 meta.timestamp = Math.round(new Date(meta.Date).getTime() / 1000); } return { diff --git a/package.json b/package.json index 40ac62f7..38646af1 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "compile": "./index.js" + "start": "./index.js" }, "keywords": [ "blog", diff --git a/theme/index.html b/theme/index.html index 947aa367..d15822c0 100644 --- a/theme/index.html +++ b/theme/index.html @@ -6,7 +6,7 @@ - + @@ -31,7 +31,7 @@