Skip to content

Instantly share code, notes, and snippets.

@apla
Last active December 29, 2015 20:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apla/7725812 to your computer and use it in GitHub Desktop.
Save apla/7725812 to your computer and use it in GitHub Desktop.
script to retrieve whole pack of formats for one google font

may 14, 2014

• added help • fixed some issues for fonts with space in family name

#!/usr/bin/env node
var http = require ('http');
var url = require ('url');
var fs = require ('fs');
var path = require ('path');
/*
usage: script family variants subset
for example: node get-google-fonts.js Roboto 100,400,700,100italic latin,cyrillic
*/
var argv = process.argv;
if (argv.length < 3) {
console.log ("usage: script family variants subset");
console.log ("for example:\n", argv[0], argv[1], "\"Roboto\" 100,400,700,100italic latin,cyrillic");
process.kill ();
}
var family = argv[2];
var variants = argv[3] || '400';
var subset = argv[4] || 'latin';
family = family.replace (/\s/g, "+");
var reqUrl = 'http://fonts.googleapis.com/css?family='+family+':'+variants+'&subset='+subset;
console.log (reqUrl);
var uaTTF = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.54.16 (KHTML, like Gecko) Version/5.1.4 Safari/534.54.16';
var uaEOT = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)';
var uaWOFF = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9) AppleWebKit/537.71 (KHTML, like Gecko) Version/7.0 Safari/537.71';
remoteResource (reqUrl, uaTTF, cssLoaded, die);
remoteResource (reqUrl, uaEOT, cssLoaded, die);
remoteResource (reqUrl, uaWOFF, cssLoaded, die);
var cssChunks = [];
var cssData = {};
function die (e) {
console.error (e);
process.terminate ();
}
function fontLoaded (fileName, reqParams, res, fontDataBuffer) {
fs.writeFile (fileName, fontDataBuffer);
return fileName;
}
function cssLoaded (reqParams, res, bodyBuffer) {
var body = bodyBuffer.toString();
var regexp = "font-family: ([^;]+)[^]+?font-style: ([^;]+)[^]+?font-weight: ([^;]+)[^]+?local\\(\\'([^\\']+)\\'\\), local\\(\\'([^\\s\\']+)\\'\\), url\\(([^\\)]+)\\) format\\(\\'([^\\']+)\\'\\)";
var gRegexp = new RegExp (regexp, "g");
var matches = body.match (gRegexp);
matches.forEach (function (item) {
var iRegexp = new RegExp (regexp, "");
var fontItem = item.match (iRegexp);
console.log ('font name: ' + fontItem[5] + ' font url: ' + fontItem[6]);
var fileName = fontItem[5] + path.extname (url.parse(fontItem[6]).pathname);
var fontVariant = fontItem[1] + "-" + fontItem[2] + "-" + fontItem[3];
if (!cssData[fontVariant]) {
cssData[fontVariant] = {
"font-family": fontItem[1],
"font-style": fontItem[2],
"font-weight": fontItem[3],
src: {
local: fontItem[4],
local2: fontItem[5]
}
};
}
cssData[fontVariant].src[fontItem[7]] = fileName;
remoteResource (fontItem[6], null, function (reqParams, res, bodyBuffer) {
var newName = fontLoaded (fileName, reqParams, res, bodyBuffer);
}, die);
body = body.replace (fontItem[6], fileName);
});
cssDone (body);
}
function cssDone (cssChunk) {
cssChunks.push (cssChunk);
if (cssChunks.length == 3) {
var buf = '';
var keys = Object.keys(cssData);
keys.forEach (function (k) {
item = cssData[k];
buf += "@font-face {\n";
buf += "\tfont-family: "+item["font-family"]+";\n";
buf += "\tfont-style: "+item["font-style"]+";\n";
buf += "\tfont-weight: "+item["font-weight"]+";\n";
buf += "\tsrc: url("+item.src["embedded-opentype"]+");\n";
buf += "\tsrc: local("+item.src.local+"), local("+item.src.local2+"), ";
buf += "url("+item.src["truetype"]+") format('truetype'), ";
buf += "url("+item.src["embedded-opentype"]+") format('embedded-opentype'), ";
buf += "url("+item.src["woff"]+") format('woff');\n}\n\n";
// fs.write ();
});
fs.writeFile (family.replace (/\+/g, '-') + '-font.css', buf);
// console.log (JSON.stringify (cssData));
}
}
function remoteResource (reqUrl, ua, success, failure) {
// console.log ("ua:", ua);
var reqParams = url.parse (reqUrl);
var req = http.request(reqUrl, function(res) {
// console.log("Got response: " + res.statusCode);
var bodyBuffer = new Buffer (0);
res.on('data', function (chunk) {
// console.log('BODY: ' + chunk);
bodyBuffer += chunk;
});
res.on ('end', function () {
// console.log (body);
// var body = bodyBuffer.toString();
success (reqParams, res, bodyBuffer);
});
});
req.on('error', function(e) {
console.log("Got error: " + e.message);
failure (e);
});
req.setTimeout (10000);
req.setHeader ('User-Agent', ua);
req.end();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment