when all you have is a hammer, everything looks like javascript - ebookcraft 2015 - baldur bjarnason
TRANSCRIPT
When all you have is a hammer, everything looks
like JavaScript
I’m Baldur BjarnasonMy job at Unbound is to, over time, automate everything
that can be automated about our ebook production
My goal is to convince you of two things
• That software projects should start small and scale up
• That Javascript is the tool for the job
Javascript all the things!
Alternate title for this talk…
Really? That can’t be a good idea.
Tool-buying versus
Tool-making
Tool-making starts small
Small, hacky solutions build up to larger things
The case for javascript
JS is web nativeIt mixes well with HTML and CSS
JS as a skill is eminently reusable
Used in browsers, app automation, servers, plugins, mobile apps, you name it
Node.js
• Opens up the possibility of standalone scripts
• No browser necessary
• Modularity let’s you start small and add as you iterate
Node.js makes javascript fun
The laws of software development
Gall’s law"A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system."
Let’s start off by taking something BBedit does
well and do it badly
var fs = require("fs"); var glob = require(‘glob’); var files = glob.sync(‘*.html’);
bodyre = new RegExp('(<h1[^>]*>|</h1>)', 'ig');
files.forEach(function(textname) { var text = fs.readFileSync(textname, "utf8"); var title = text.split(bodyre)[2]; console.log(title); });
The limits of Regular Expressions
<[^<>/]*?class=\”random-class-thing"[^<>/]*?>)([^<>]*?)(</[^<>/]*?>
versus
document.querySelectorAll('random-class-thing');
var fs = require("fs");
var jsdom = require("jsdom");
var jquery = require("jquery");
book = fs.readFileSync("eBook Test-5March14.html", "utf8");
jsdom.env({
html: book,
done: function (errors, window) {
jquery(window);
window.$("h4").unwrap();
window.$("h1").addClass("test2");
fs.writeFileSync("bookbody3.html", window.document.documentElement.innerHTML);
}
});
The tool-making bit:#!/usr/bin/env node
'use strict'; var program = require(‘commander'); program.version('0.1.0') .option('-f, --folder [path]', 'Output folder') .option('-o, --output [filename]', 'Filename') .option('-v, --verbose', "Let's be chatty and loud") .option('-m, --mangle', 'Obfuscate the font files');
Are we having fun yet?
The recipe for success
• One part hacky node.js scripts
• One part commander (or similar module)
• Mix well over time
• And the result…
Tools!
var mangler = function(fontpath, id) {
var font = fs.readFileSync(fontpath);
var shasum = crypto.createHash('sha1').update(id.trim(), 'utf8');
var key = new Buffer(shasum.digest('hex'), 'hex');
var prefix = font.slice(0, 1040);
var _fn = function(blob, i) { return prefix[i] = blob ^ key[i % key.length]; };
for (i = _i = 0, _len = prefix.length; _i < _len; i = ++_i) {
var blob = prefix[i];
_fn(blob, i);
}
font2 = Buffer.concat([prefix, font.slice(1040)]);
fs.writeFileSync(fontpath, font2);
};
That was a kick in the faceBut can you guess what it was for?
Learning JS
• Mozilla’s re-introduction to JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
• Eloquent JavaScript http://eloquentjavascript.net
• JavaScript: The Good Parts by Douglas Crockford
Learning JS
• Khan Academy: http://www.khanacademy.org/computing/computer-programming
• Codecademy: http://www.codecademy.com/tracks/javascript