Skip to content

Instantly share code, notes, and snippets.

@maryo
Created January 28, 2019 01:24
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save maryo/1bc0ef4c42f0eb8a4b861284ed906299 to your computer and use it in GitHub Desktop.
Save maryo/1bc0ef4c42f0eb8a4b861284ed906299 to your computer and use it in GitHub Desktop.
Typekit font downloader
const https = require('https');
const fs = require('fs');
// https://github.com/majodev/google-webfonts-helper/blob/master/server/logic/conf.js
const FORMAT_USER_AGENTS = {
// see http://www.dvdprojekt.de/category.php?name=Safari for a list of sample user handlers
// test generation through running grunt mochaTest:src
eot: 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)',
woff: 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0',
// must serve complete woff2 file for one variant (no unicode range support yet!)
// see http://www.useragentstring.com/pages/Firefox/
// see http://caniuse.com/#search=woff2
// see http://caniuse.com/#feat=font-unicode-range
// see https://developers.googleblog.com/2015/02/smaller-fonts-with-woff-20-and-unicode.html
woff2: 'Mozilla/5.0 (Windows NT 6.3; rv:39.0) Gecko/20100101 Firefox/39.0',
svg: 'Mozilla/4.0 (iPad; CPU OS 4_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/4.1 Mobile/9A405 Safari/7534.48.3',
ttf: 'Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) Safari/538.1 Daum/4.1'
};
const FORMAT_EXTENSIONS = {
'truetype': 'ttf',
'opentype': 'otf',
'embedded-opentype': 'eot',
};
const STYLE_URL = 'https://use.typekit.net/uvx5cke.css';
const downloadedFonts = {};
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
for (const format in FORMAT_USER_AGENTS) {
const headers = {'User-Agent': FORMAT_USER_AGENTS[format]};
https.get(STYLE_URL, {headers}, (response) => {
if (response.statusCode !== 200) {
throw new Error(`Request failed. Status Code: ${response.statusCode}.`);
}
let content = '';
response.on('data', (chunk) => {
content += chunk;
});
response.on('end', () => {
for (const fontFaceRule of content.match(/@font-face {[^}]+}/g)) {
const fontFamily = fontFaceRule.match(/font-family:\s*"([^"]+)"/)[1];
const fontWeight = fontFaceRule.match(/font-weight:\s*([^;]+);/)[1];
const fontStyle = fontFaceRule.match(/font-style:\s*([^;]+);/)[1];
const fontUrlAndFormats = fontFaceRule.match(/url\("([^"]+)"\)\s+format\("([^"]+)"\)/g);
for (const fontUrlAndFormat of fontUrlAndFormats) {
const fontUrl = fontUrlAndFormat.match(/url\("([^"]+)"\)/)[1];
const fontFormat = fontUrlAndFormat.match(/format\("([^"]+)"\)/)[1].toLowerCase();
const extension = FORMAT_EXTENSIONS[fontFormat] || fontFormat;
const filename = `${fontFamily}_${fontWeight}_${fontStyle}.${extension}`;
if (!downloadedFonts[filename]) {
https.get(fontUrl, (response) => {
console.log(`Downloaded "${fontFamily}" font family for "${fontFormat}" format in ${fontWeight} weight and ${fontStyle} style.`);
response.pipe(fs.createWriteStream(`downloads/${filename}`));
});
}
}
}
});
});
}
@juukie
Copy link

juukie commented Dec 3, 2021

Works great, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment