diff --git a/package.json b/package.json index 0d5d0ae..2d45432 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,9 @@ "description": "An emoji guide for your commit messages", "main": "index.js", "scripts": { - "jsonvalidate": "jsonlint ./src/data/gitmojis.json -V ./src/data/schema.json", - "contributors": "curl https://api.github.com/repos/carloscuesta/gitmoji/contributors -o ./src/data/contributors.json", - "start": "npm run contributors && gulp", + "jsonvalidate": "jsonlint ./src/data/gitmojis.json -V ./src/data/schema.json", + "contributors": "curl https://api.github.com/repos/carloscuesta/gitmoji/contributors -o ./src/data/contributors.json", + "start": "npm run contributors && gulp", "test": "npm run jsonvalidate && gulp test" }, "repository": { @@ -26,17 +26,22 @@ "requireLowerCaseAttributes": true }, "babel": { - "presets": ["es2015"] + "presets": [ + "es2015" + ] }, "homepage": "https://github.com/carloscuesta/gitmoji#readme", "dependencies": { + "async": "^2.1.2", "babel-core": "^6.18.0", "babel-preset-es2015": "^6.18.0", "gulp": "^3.9.1", "gulp-plumber": "^1.1.0", "gulp-pug": "^3.1.0", "gulp-pug-lint": "^0.1.6", - "gulp-sass": "^2.3.2" + "gulp-sass": "^2.3.2", + "pdfkit": "^0.8.0", + "request": "^2.79.0" }, "devDependencies": { "browser-sync": "^2.17.5", diff --git a/src/pdf/index.js b/src/pdf/index.js new file mode 100644 index 0000000..9518d87 --- /dev/null +++ b/src/pdf/index.js @@ -0,0 +1,70 @@ +'use strict'; + +const PDFDocument = require('pdfkit'); +const fs = require('fs'); +const path = require('path'); +const loadEmoji = require('./loadEmojis'); + +const __root = path.join(__dirname, '/../../'); + +// The layout of the PDF document +const layout = { + leftMargin: 60, + topMargin: 100, + emojiSpace: 38, + emojiSize: 32, + + emojisHigh: 16, + secondMargin: 260, + + textLeftMargin: 40, + textDescTopMargin: 18 +}; + +// Check if directories exists, otherwise create them. +if(!fs.existsSync(__root+'dist/')) { + fs.mkdirSync(__root+'dist'); + fs.mkdirSync(__root+'dist/pdf'); + fs.mkdirSync(__root+'dist/pdf/emojis'); +} else if(!fs.existsSync(__root+'dist/pdf')){ + fs.mkdirSync(__root+'dist/pdf'); + fs.mkdirSync(__root+'dist/pdf/emojis'); +} + +var emojiList = null; + +loadEmoji(function (emojis) { + console.log("Done fetching images"); + emojiList = emojis; + + // Wait for images to write to disk + setTimeout(generatePDF, 1000); +}); + +function generatePDF() { + console.log("Generating PDF"); + var doc = new PDFDocument; + doc.pipe(fs.createWriteStream(__root+'dist/pdf/cheatsheet.pdf')); + + doc.fontSize(32).text('Gitmoji Cheatsheet', 40, 40); + + for (var i = 0; i < emojiList.length; i++) { + var emoji = emojiList[i]; + + var x = layout.leftMargin + Math.floor(i/layout.emojisHigh)*layout.secondMargin; + var y = layout.topMargin+ layout.emojiSpace * (i%layout.emojisHigh); + + if(Math.floor(i%(layout.emojisHigh*2))==0 && i!=0){ + doc.addPage(); + } + + doc.image(__root+'dist/pdf/emojis/'+emoji.name+'.png', x, y, {width: layout.emojiSize}); + doc.fontSize(14).text(emoji.code, x+layout.textLeftMargin, y); + doc.fontSize(11).text(emoji.description, x+layout.textLeftMargin, y+layout.textDescTopMargin); + + } + + doc.end(); + console.log('PDF generated successfully'); + console.log('Location: '+path.resolve(__root, 'dist/pdf/cheatsheet.pdf')); +} \ No newline at end of file diff --git a/src/pdf/loadEmojis.js b/src/pdf/loadEmojis.js new file mode 100644 index 0000000..66fe695 --- /dev/null +++ b/src/pdf/loadEmojis.js @@ -0,0 +1,105 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const request = require('request'); +const async = require('async'); + +const __root = path.join(__dirname, '/../../'); + +var emojiList = null; +var emojiUrls = null; + +var loadEmojis = function(callback){ + + if(emojiList==null) + emojiList = JSON.parse(fs.readFileSync(__root+'src/data/gitmojis.json')).gitmojis; + + checkEmojis(function (err, emojisToDownload) { + if(err) throw err; + + // Only send a request to Github, if some icons need to be downloaded + if(emojisToDownload.length>0){ + fetchEmojiUrls(function () { + downloadEmojis(); + }); + } else downloadEmojis(); + + function downloadEmojis() { + async.each(emojisToDownload, downloadEmoji, function (err) { + if(err) throw err; + callback(emojiList); + }); + } + + }); + + // Functions + + // Get emoji image urls, from Github + function fetchEmojiUrls(callback) { + var options = { + url: 'https://api.github.com/emojis', + headers: { + 'User-Agent': 'gitmoji' + } + }; + + request(options, function (err, res, body) { + if(err) throw err; + if(res.statusCode!=200) throw new Error('Server responded with non 200 code'); + + emojiUrls = JSON.parse(body); + callback(); + }); + } + + // Gets a list from gitmojis.json, of all the emoji icons to download. + function checkEmojis(callback) { + var emojisToDownload = []; + + async.each(emojiList, function (emoji, callback) { + fs.access(__root+'dist/pdf/emojis/'+emoji.name+'.png', function (err) { + // Returns an error, if image wasn't found + if(err){ + emojisToDownload.push(emoji); + callback(null); + } else { + console.log("Emoji found: "+emoji.name); + callback(null); + } + }); + }, function (err) { + callback(err, emojisToDownload); + }); + } + + // Downloads an emoji from Github + function downloadEmoji(emoji, callback) { + console.log("Emoji downloading: "+emoji.name); + + var url = emojiUrls[emoji.code.substring(1, emoji.code.length-1)]; + + if(url==null){ + throw new Error('Emoji url not found, for emoji: '+emoji.code); + } + + var options = { + url: url, + headers: { + 'User-Agent': 'gitmoji' + } + }; + + request(options, function (err, res) { + if(err) throw err; + if(res.statusCode!=200) throw new Error('Server responded with non 200 code'); + }).on('end', function () { + console.log("Emoji successfully downloaded: "+emoji.name); + emoji.path = path.resolve(__root+'dist/pdf/emojis/'+emoji.name+'.png'); + callback(null, emoji); + }).pipe(fs.createWriteStream(__root+'dist/pdf/emojis/'+emoji.name+'.png')); + } +}; + +module.exports = loadEmojis; \ No newline at end of file