Skip to content

Instantly share code, notes, and snippets.

@maryo
Created January 28, 2019 01:24
Show Gist options
  • Select an option

  • Save maryo/1bc0ef4c42f0eb8a4b861284ed906299 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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