diff --git a/.editorconfig b/.editorconfig index e7724918..cf166dfb 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,3 +12,6 @@ indent_size = 2 [*.md] trim_trailing_whitespace = false + +[*.json] +insert_final_newline = false diff --git a/converter.js b/converter.js index 5684f474..fb8c643d 100755 --- a/converter.js +++ b/converter.js @@ -1,15 +1,12 @@ #!/usr/bin/env node 'use strict'; -/* global DateSetFromIsoString */ - var fs = require('fs-extra'); var pkg = JSON.parse(fs.readFileSync('./package.json')); - -var glob = require("glob"); +var glob = require("glob"); var readline = require("readline"); -var yamljs = require('yamljs'); +var yamljs = require('yamljs'); /** * Convert given UTC string into Date object diff --git a/index.js b/index.js index b4540704..7f9b4dae 100755 --- a/index.js +++ b/index.js @@ -1,13 +1,9 @@ #!/usr/bin/env node 'use strict'; -var fs = require('fs-extra'); -var pkg = JSON.parse(fs.readFileSync('./package.json')); -var config = JSON.parse(fs.readFileSync('./user/config.json')); - var Generator = require('./lib/generator'); -Generator.init(config, pkg); +Generator.init(); Generator.on('articlesBuild', function (post) { Generator.buildOtherPages(); Generator.copyImages(); diff --git a/lib/config.js b/lib/config.js new file mode 100644 index 00000000..552d709f --- /dev/null +++ b/lib/config.js @@ -0,0 +1,9 @@ +'use strict'; + +var fs = require('fs-extra'); +var config = JSON.parse(fs.readFileSync('./user/config.json')); +var pkg = JSON.parse(fs.readFileSync('./package.json')); + +config.directories = pkg.directories; + +module.exports = config; diff --git a/lib/generator.js b/lib/generator.js index 497c38b4..3cec946e 100644 --- a/lib/generator.js +++ b/lib/generator.js @@ -6,6 +6,8 @@ var fs = require('fs-extra'); var shell = require('shelljs'); var glob = require("glob"); var PostReader = require('./post_reader'); +var config = require('./config'); +var gm = require('gm').subClass({imageMagick: true}); /** * Generator used for creating the blog @@ -13,23 +15,19 @@ var PostReader = require('./post_reader'); */ var Generator = new EventEmitter(); -var config = {}, pkg = {}, templates; +var 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; +Generator.init = function ( ) { 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') + post: fs.readFileSync(config.directories.theme+'/post.html', 'utf8'), + index: fs.readFileSync(config.directories.theme+'/index.html', 'utf8'), + rss: fs.readFileSync(config.directories.theme+'/rss.xml', 'utf8'), + sitemap: fs.readFileSync(config.directories.theme+'/sitemap.xml', 'utf8') }; Object.keys(templates).map(function (template) { @@ -42,12 +40,12 @@ Generator.init = function ( Cconfig, Cpkg ) { * @return {[type]} [description] */ Generator.buildArticles = function () { - glob(pkg.directories.data + "/**/*.md", function (er, files) { + glob(config.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, { + shell.mkdir('-p', config.directories.htdocs + '/' + post.meta.Url); + fs.writeFile(config.directories.htdocs + '/' + post.meta.Url + 'index.html', Mustache.render(templates.post, { meta: post.meta, content: post.html, config: config @@ -74,29 +72,29 @@ Generator.buildArticles = function () { Generator.buildOtherPages = function ( ) { var pagedPosts = index.getPagedPosts(5), page, indexFilename; - fs.writeFile(pkg.directories.htdocs + '/sitemap.json', JSON.stringify(index.getPosts()), function() { + fs.writeFile(config.directories.htdocs + '/sitemap.json', JSON.stringify(index.getPosts()), function() { console.log("Wrote sitemap.json"); }); - fs.remove(pkg.directories.htdocs + '/index*', function (err) { + fs.remove(config.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() { + fs.writeFile(config.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, { + fs.writeFile(config.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, { + fs.writeFile(config.directories.htdocs + '/sitemap.xml', Mustache.render(templates.sitemap, { index: index.getPosts(10), config: config }),function () { @@ -104,11 +102,11 @@ Generator.buildOtherPages = function ( ) { }); var tags = index.getTags(); - fs.remove(pkg.directories.htdocs + '/tagged', function (err) { + fs.remove(config.directories.htdocs + '/tagged', function (err) { Object.keys(tags).map(function (key) { - shell.mkdir('-p', pkg.directories.htdocs + '/tagged/' + tags[key].id); + shell.mkdir('-p', config.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() { + fs.writeFile(config.directories.htdocs + '/tagged/' + tags[key].id + '/index.html', Mustache.render(templates.index, tags[key]), function() { console.log("Wrote tagged/" + tags[key].id + '/index.html'); }); }); @@ -116,7 +114,7 @@ Generator.buildOtherPages = function ( ) { }; Generator.copyImages = function () { - glob(pkg.directories.data + "/**/*.{png,jpg,gif}", function (er, files) { + glob(config.directories.data + "/**/*.{png,jpg,gif}", function (er, files) { var i, copiedFiles = 0; var copyEnd = function () { copiedFiles ++; @@ -125,7 +123,18 @@ Generator.copyImages = function () { } }; for (i = 0; i < files.length; i++) { - fs.copy(files[i], files[i].replace(/^user\//, 'htdocs/'), copyEnd); + var targetFile = files[i].replace(/^user\//, config.directories.htdocs + '/'); + fs.copy(files[i], targetFile, copyEnd); + config.imageSizes.forEach(function(imageSize) { + // console.log(targetFile.replace(/(\.[a-z]+$)/,'-'+imageSize[0]+'x'+imageSize[1]+'$1')); + gm(files[i]) + .resize(imageSize[0], imageSize[1]) + .noProfile() + .write(targetFile.replace(/(\.[a-z]+$)/,'-'+imageSize[0]+'x'+imageSize[1]+'$1'),function() { + + }) + ; + }) } }); }; diff --git a/lib/post.js b/lib/post.js index 3289d4d0..faad5abb 100644 --- a/lib/post.js +++ b/lib/post.js @@ -1,29 +1,17 @@ 'use strict'; -var fs = require('fs'); +var fs = require('fs'); var markdownConvert = require('marked'); -var config = JSON.parse(fs.readFileSync('./user/config.json')); -var dateFormat = require('dateformat'); -var toolshed = require('./js-toolshed/src/js-toolshed'); +var config = require('./config'); +var dateFormat = require('dateformat'); +var toolshed = require('./js-toolshed/src/js-toolshed'); var markyMark = function (html, relUrl) { if (relUrl) { html = html.replace(/(!\[.+?\]\()/g, '$1'+relUrl); } - return markdownConvert(html) - .replace(/

===<\/p>/g,'') - .replace(/(<\/?h)3/g,'$14') - .replace(/(<\/?h)2/g,'$13') - .replace(/(<\/?h)1/g,'$12') - .replace( - /(

)\s*(?:)?[^<]*?youtube.+v=([a-zA-Z0-9\-_]+)[^>]*?(?:<\/a>)?\s*(<\/p>)/g, - '

' - ) - .replace( - /(

)\s*(?:)?[^<]*?vimeo.com\/(\d+)[^>]*?(?:<\/a>)?\s*(<\/p>)/g, - '

' - ) - .replace(/--/g, '—') + html = html + .replace(/\s--\s/g, ' — ') .replace(/\.\.\./g, '…') .replace(/… …/g, '… ') .replace(/\(C\)/g, '©') @@ -40,6 +28,22 @@ var markyMark = function (html, relUrl) { .replace(/(\d)\s*-\s*(\d)/g,'$1–$2') .replace(/(\s)-(\s)/g,'$1–$2') .replace(/(\d\s*)(x|\*)(\s*\d)/g,'$1×$3') + .replace(/"(\S.*?\S)"/g,'„$1“') + .replace(/'(\S.*?\S)'/g,'‚$1‘') + ; + return markdownConvert(html) + .replace(/

===<\/p>/g,'') + .replace(/(<\/?h)3/g,'$14') + .replace(/(<\/?h)2/g,'$13') + .replace(/(<\/?h)1/g,'$12') + .replace( + /(

)\s*(?:)?[^<]*?youtube.+v=([a-zA-Z0-9\-_]+)[^>]*?(?:<\/a>)?\s*(<\/p>)/g, + '

' + ) + .replace( + /(

)\s*(?:)?[^<]*?vimeo.com\/(\d+)[^>]*?(?:<\/a>)?\s*(<\/p>)/g, + '

' + ) ; }; @@ -48,7 +52,7 @@ var markyMark = function (html, relUrl) { * @constructor */ var Post = function (markdown, meta) { - var htmlTeaser = markyMark(meta.Description.trim() || '', config.basePath + meta.Url); + var htmlTeaser = markyMark(meta.Description.trim() || '', meta.Url); if (meta.Keywords !== undefined) { meta.Tags = []; meta.Keywords.trim().split(/,\s+/).forEach(function(tag){ @@ -73,7 +77,7 @@ var Post = function (markdown, meta) { return { markdown: markdown, meta: meta, - html: markyMark(markdown), + html: markyMark(markdown, meta.Url), htmlTeaser: htmlTeaser }; }; diff --git a/lib/post_reader.js b/lib/post_reader.js index ef2104c6..68751c9d 100644 --- a/lib/post_reader.js +++ b/lib/post_reader.js @@ -1,6 +1,12 @@ 'use strict'; var EventEmitter = require( "events" ).EventEmitter; +var fs = require('fs'); +var config = require('./config'); +var Post = require('./post'); +var readline = require("readline"); +var yamljs = require('yamljs'); +var util = require('util'); /** * Represents a single blog item. @@ -9,12 +15,6 @@ var EventEmitter = require( "events" ).EventEmitter; var PostReader = new EventEmitter(); PostReader.parse = function ( file ) { - var Post = require('./post'); - var fs = require('fs'); - var readline = require("readline"); - var yamljs = require('yamljs'); - var util = require('util'); - EventEmitter.call(this); var readYaml = true, yamlBuffer = '', @@ -36,6 +36,8 @@ PostReader.parse = function ( file ) { }).on('line', function (line) { if (readYaml && line.match(/\S+:[\s\S]/)) { yamlBuffer += line + "\n"; + } else if(readYaml && line.match(/^---$/)) { + // do nothing } else { if (readYaml) { readYaml = false; @@ -71,7 +73,7 @@ PostReader.parse = function ( file ) { exports.meta.Date = fileStat.mtime; } - exports.meta.Url = file.replace(/user\//,'').replace(/\.md$/,'/'); + exports.meta.Url = file.replace(/user\//,config.basePath).replace(/\.md$/,'/'); //console.log(exports); PostReader.emit('parsed', Post(exports.markdown, exports.meta)); diff --git a/package.json b/package.json index 38646af1..a7a815fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blogophon", - "version": "0.0.1", + "version": "0.0.2", "description": "Most-simple blog", "main": "index.js", "scripts": { @@ -13,6 +13,7 @@ ], "devDependencies": { "beepbeep": "^1.2.0", + "gm": "^1.23.0", "gulp": "^3.9.1", "gulp-jshint": "^2.0.1", "gulp-livereload": "^3.8.1", diff --git a/user/_config.json b/user/_config.json index bec0ed2f..9104beb3 100644 --- a/user/_config.json +++ b/user/_config.json @@ -4,5 +4,10 @@ "basePath": "/", "description": "Most-simple blog", "language": "en", - "deploy":"" + "deploy":"", + "imageSizes": [ + [200,200], + [320,640], + [800,600] + ] }