diff --git a/bin/generate-screenshots.js b/bin/generate-screenshots.js index d95ffc3..f78e311 100755 --- a/bin/generate-screenshots.js +++ b/bin/generate-screenshots.js @@ -5,6 +5,22 @@ const buffer2stream = require('buffer-to-stream'); const fs = require('fs'); const PngCrush = require('pngcrush'); const svg2png = require('svg2png'); +const util = require('util'); + +const readFile = util.promisify(fs.readFile); +const writeFile = util.promisify(fs.writeFile); + +function make(parent, tag, attrs = {}) { + const doc = parent.ownerDocument; + const element = doc.createElement(tag); + for(const k in attrs) { + if(Object.prototype.hasOwnProperty.call(attrs, k)) { + element.setAttribute(k, attrs[k]); + } + } + parent.appendChild(element); + return element; +} function read(pipe) { return new Promise((resolve) => { @@ -31,15 +47,7 @@ function processError(err) { function getReadmeFile() { if(process.argv.length > 2 && process.argv[2] !== '-') { - return new Promise((resolve, reject) => { - fs.readFile(process.argv[2], (err, data) => { - if(err) { - reject(err); - } else { - resolve(data); - } - }); - }); + return readFile(process.argv[2]); } else { process.stdin.setEncoding('utf8'); return read(process.stdin); @@ -84,6 +92,47 @@ function findSamples(content) { * }); */ + results.push({ + code: ( + 'theme monospace\n' + + 'begin A, B\n' + + 'A -> B: sequence\n' + + 'B -> A: diagram\n' + ), + file: 'web/resources/apple-touch-icon.png', + mutator: (diagram) => { + const base = diagram.dom(); + const [defs] = base.getElementsByTagName('defs'); + const grad = make(defs, 'linearGradient', { + 'id': 'background', + 'x1': 0, + 'x2': 0, + 'y1': 0.1, + 'y2': 0.9, + }); + make(grad, 'stop', {'offset': '0%', 'stop-color': '#9BCDFD'}); + make(grad, 'stop', {'offset': '100%', 'stop-color': '#8BC2FF'}); + + const offset = 5; + const size = diagram.getSize(); + const fill = make(base, 'rect', { + 'fill': 'url(#background)', + 'height': size.height * 1.2, + 'width': size.width * 1.2, + 'x': -offset - size.width * 0.1, + 'y': -offset - size.height * 0.1, + }); + base.insertBefore(fill, base.firstChild); + + for(const txt of base.getElementsByTagName('text')) { + const sz = txt.getAttribute('font-size'); + txt.setAttribute('font-size', sz * 1.2); + txt.setAttribute('font-family', 'courier'); + } + }, + size: {height: 432, width: 432}, + }); + return results; } @@ -102,7 +151,7 @@ function compressImageBuffer(buffer) { return stream2buffer(compressed); } -function renderSample({file, code, size}) { +function renderSample({file, code, mutator, size}) { process.stdout.write('generating ' + file + '\n'); const diagram = new VirtualSequenceDiagram(code); @@ -117,18 +166,14 @@ function renderSample({file, code, size}) { height = diagram.getSize().height * RESOLUTION; } + if(mutator) { + mutator(diagram); + } + return diagram.getSVGCode() .then((svg) => svg2png(svg, {height, width})) .then(compressImageBuffer) - .then((buffer) => new Promise((resolve, reject) => { - fs.writeFile(file, buffer, {mode: 0o644}, (err) => { - if(err) { - reject(err); - } else { - resolve(); - } - }); - })) + .then((buffer) => writeFile(file, buffer, {mode: 0o644})) .then(() => process.stdout.write(file + ' complete\n')) .catch((err) => process.stderr.write( 'Failed to generate ' + file + ': ' + diff --git a/web/resources/apple-touch-icon.png b/web/resources/apple-touch-icon.png index 718f201..10f5f3d 100644 Binary files a/web/resources/apple-touch-icon.png and b/web/resources/apple-touch-icon.png differ