From 2c73fbe4d4ca7a4913a8ffcdc865ae51bc85b1c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Sko=C5=99epa?= <jakub@skorepa.info> Date: Tue, 19 Apr 2016 17:14:39 +0200 Subject: [PATCH] Implement image minification TODO: Implement caching mechanism to speed up the process --- sitegin/image.js | 68 +++++++++++++++++++++++++++++------------ sitegin/imageResizer.js | 54 ++++++++++++++++++++++++++++++++ sitegin/markdown.js | 6 ++-- sitegin/pipeline.js | 2 +- sitegin/sitegin.js | 1 + sitegin/urls.js | 13 +++++--- 6 files changed, 117 insertions(+), 27 deletions(-) create mode 100644 sitegin/imageResizer.js diff --git a/sitegin/image.js b/sitegin/image.js index 776cf8e6..7a5a3638 100644 --- a/sitegin/image.js +++ b/sitegin/image.js @@ -2,6 +2,13 @@ var youtube = require('./utils/youtube.js'); var path = require('path'); +var url = require('url'); +var jobs = require('./jobs'); +var rewriteURL = require('./urls').rewriteURL; + +var generateImage = function(file, targetDir, width, height) { + return jobs.run('imageResizer', file, targetDir, width, height); +} var paramInHrefParser = function(href) { var sepIndex = href.indexOf(' ='); @@ -42,7 +49,7 @@ var renderYoutube = function(href, options) { return out; } -module.exports = function(href, title, text, curFilename) { +module.exports = function(href, title, text, curFile, cfg) { var parsed = paramInHrefParser(href); href = parsed.href; var options = parsed.options; @@ -66,28 +73,51 @@ module.exports = function(href, title, text, curFilename) { if(youtube.isVideo(href)) { return renderYoutube(href, options); } else { - var rel = path.relative(process.cwd(),path.resolve(curFilename,href)); + var genHTML = function(file) { + var rel = path.relative(process.cwd(),file); - var out = '<img src="' + href + '" alt="' + text + '"'; - if(options.width) { - out += ' width="' + options.width + '"'; - } - if(options.height) { - out += ' height="' + options.height + '"'; - } - if (title) { - out += ' title="' + title + '"'; + var out = '<img src="' + rel + '" alt="' + text + '"'; + if(options.width) { + out += ' width="' + options.width + '"'; + } + if(options.height) { + out += ' height="' + options.height + '"'; + } + if (title) { + out += ' title="' + title + '"'; + } + + out += '>'; + if(!options.nolightbox) { // if lightbox + var a = '<a href="'+href+'"'; + a += ' data-lightbox="group"'; + a += ' data-title="' + text + '"'; + a += '>'; + out = a+out+'</a>'; + } + return out; } + var parsedHref = url.parse(href); + + if(parsedHref.host) { + genHTML(href); + } else if(path.isAbsolute(href)) { + genHTML(href); + } else { + curFile = curFile.replace(/\.md$/,''); + var targetDir = rewriteURL(curFile); + targetDir = path.resolve(cfg.builddir, targetDir); + var absSrc = path.resolve(cfg.staticDir, curFile, href); - out += '>'; - if(!options.nolightbox) { // if lightbox - var a = '<a href="'+href+'"'; - a += ' data-lightbox="group"'; - a += ' data-title="' + text + '"'; - a += '>'; - out = a+out+'</a>'; + if(!options.size) options.size = []; + var w = options.size[0], + h = options.size[1]; + if(w === '') w = undefined; else w = Number(w); + if(h === '') h = undefined; else h = Number(h); + if(w === undefined && h === undefined) w = 512; + var file = generateImage(absSrc, targetDir, w, h); + return genHTML(file); } - return out; } } diff --git a/sitegin/imageResizer.js b/sitegin/imageResizer.js new file mode 100644 index 00000000..204325fb --- /dev/null +++ b/sitegin/imageResizer.js @@ -0,0 +1,54 @@ +var lwip; +var path = require('path'); +try {lwip = require('lwip');} +catch(e) { + lwip = null + console.log('WARNING! LWIP is not installed - image minification won\'t work.'); + console.log('You can try to run npm install.'); + console.log('If it does not help try to make npm install lwip work.'); +} + +module.exports = function(file, targetDir, width, height) { + if(lwip && (width || height)) { + var tmp = path.basename(file).split('.'); + tmp.splice(-1,1); + var base = tmp.join('.'); + var targetFile = base+'_thumb_'; + if(width) targetFile += width; + targetFile += 'x'; + if(height) targetFile += height; + targetFile += '.png'; + var ret = targetFile; + targetFile = path.resolve(targetDir,targetFile); + lwip.open(file, function(err, image) { + function doResize() { + image.batch() + .resize(width, height) + .writeFile(targetFile, function(err) { + if(err) console.log(err); + }); + } + + if(err) return console.log(err); + var w = image.width(), h = image.height(); + if(width && height) { + doResize(); + } else if(height) { + if(h > height) { + width = Math.round(height*w/h); + doResize(); + } + } else if(width) { + if(w > width) { + height = Math.round(width*h/w); + doResize(); + } + } else { + console.log(new Error('Panic! Code should never get here!')); + } + }) + return ret; + } else { + return file; + } +} diff --git a/sitegin/markdown.js b/sitegin/markdown.js index e6482e15..e7fe5ecc 100644 --- a/sitegin/markdown.js +++ b/sitegin/markdown.js @@ -40,8 +40,8 @@ var toURL = function(url) { return jobs.run('toURL', url); } -var renderImage = function(href, title, text, curFilename) { - return jobs.run('image', href, title, text, curFilename); +var renderImage = function(href, title, text, curFilename, cfg) { + return jobs.run('image', href, title, text, curFilename, cfg); } renderer.heading = function(text, level, raw) { @@ -81,7 +81,7 @@ module.exports = function(obj) { obj.pages.forEach(function(article) { renderer.image = function(href, title, text) { - return renderImage(href, title, text, article.filename); + return renderImage(href, title, text, article.file, obj.config); }; lang = article.metadata.lang; article.content = parser.parse(lexer.lex(article.content)); diff --git a/sitegin/pipeline.js b/sitegin/pipeline.js index 1a165148..26b791b3 100644 --- a/sitegin/pipeline.js +++ b/sitegin/pipeline.js @@ -10,9 +10,9 @@ module.exports = function(jobs) { 'parseHugo', 'parseRedirects', 'gitInfo', + 'markdown', 'urls', 'sitemap', - 'markdown', 'tags', 'theme', 'writeFiles', diff --git a/sitegin/sitegin.js b/sitegin/sitegin.js index 9ab6fbc1..e23fae14 100644 --- a/sitegin/sitegin.js +++ b/sitegin/sitegin.js @@ -19,6 +19,7 @@ module.exports = function(config) { ['sitemap', './sitemap'], ['parseRedirects','./parseRedirects'], ['image', './image'], + ['imageResizer', './imageResizer'], ['pipeline','./pipeline'] ) diff --git a/sitegin/urls.js b/sitegin/urls.js index e4263f08..57045398 100644 --- a/sitegin/urls.js +++ b/sitegin/urls.js @@ -2,15 +2,20 @@ * This jobs translates files to resulting URL */ +var rewriteURL = function(file) { + file = file.replace(/\.md$/,''); + file = file.replace(/^articles/,'clanek'); + return file; +} + module.exports = function(obj) { console.log('Build step: URLs'); return new Promise(function(resolve, reject) { obj.pages.forEach(function(page) { - var file = page.file; - file = file.replace(/\.md$/,''); - file = file.replace(/^articles/,'clanek'); - page.file = file; + page.file = rewriteURL(page.file); }) resolve(obj) }); } + +module.exports.rewriteURL = rewriteURL; -- GitLab