Skip to content

Instantly share code, notes, and snippets.

@dammyammy
Last active May 15, 2017 04:13
Show Gist options
  • Select an option

  • Save dammyammy/e0e293d6e034623ede31 to your computer and use it in GitHub Desktop.

Select an option

Save dammyammy/e0e293d6e034623ede31 to your computer and use it in GitHub Desktop.
Download Google Web fonts Locally
#!/usr/bin/env bash
#==========================================================================================
# http://fonts.googleapis.com/css?family=Nunito:300,400,700|Raleway:400,300,500,600,700
#==========================================================================================
declare -a families
families+=('Nunito:300')
families+=('Nunito:400')
families+=('Nunito:700')
families+=('Raleway:300')
families+=('Raleway:400')
families+=('Raleway:500')
families+=('Raleway:600')
families+=('Raleway:700')
#families+=('Lora:700')
#families+=('Alegreya:400')
url="http://fonts.googleapis.com/css"
css="fonts.css"
prefix="../fonts/"
# Ensure the bash version is new enough. If it isn't error out with a helpful error message rather than crashing later.
if [ ${BASH_VERSINFO[0]} -lt 4 ]; then
echo "Error: This script needs Bash 4.x to run." >&2
exit 1
fi
# Check whether sed is GNU or BSD sed, or rather, which parameter enables extended regex support. Note that GNU sed does
# have -E as an undocumented compatibility option on some systems.
if [ "$(echo "test" | sed -E 's/([st]+)$/xx\1/' 2>/dev/null)" == "texxst" ]; then
ESED="sed -E"
elif [ "$(echo "test" | sed -r 's/([st]+)$/xx\1/' 2>/dev/null)" == "texxst" ]; then
ESED="sed -r"
else
echo "Error: $(which sed) seems to lack extended regex support with -E or -r." >&2
exit 2
fi
# Store the useragents we're going to use to trick Google's servers into serving us the correct CSS file.
declare -A useragent
useragent[eot]='Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)'
useragent[woff]='Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0'
useragent[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'
useragent[ttf]='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.54.16 (KHTML, like Gecko) Version/5.1.4 Safari/534.54.16'
# Clear the output file
>"$css"
# Loop over the fonts, and download them one-by-one
for family in "${families[@]}"; do
echo -n "Downloading ${family}... "
printf "@font-face {\n" >>"$css"
# Extract name, Windows-safe filename, font style and font weight from the font family name
fontname=$(echo "$family" | awk -F : '{print $1}')
fontnameescaped=$(echo "$family" | $ESED 's/( |:)/_/g')
fontstyle=$(echo "$family" | awk -F : '{print $2}')
fontweight=$(echo "$fontstyle" | $ESED 's/italic$//g')
printf "\tfont-family: '%s';\n" "$fontname" >>"$css"
# $fontstyle could be bolditalic, bold, italic, normal, or nothing.
case "$fontstyle" in
*italic)
printf "\tfont-style: italic;\n" >>"$css"
;;
*)
printf "\tfont-style: normal;\n" >>"$css"
;;
esac
# Either bold, a number, or empty. If empty, default to "normal".
printf "\tfont-weight: %s;\n" "${fontweight:-normal}" >>"$css"
printf "\tsrc:\n" >>"$css"
# Determine the local names for the given fonts so we can use a locally-installed font if available.
local_name=$(curl -sf --get --data-urlencode "family=$family" "$url" | grep -E "src:" | $ESED "s/^.*src: local\\('([^']+)'\\),.*$/\\1/g")
local_postscript_name=$(curl -sf --get --data-urlencode "family=$family" "$url" | grep -E "src:" | $ESED "s/^.*, local\\('([^']+)'\\),.*$/\\1/g")
# Some fonts don't have a local PostScript name.
printf "\t\tlocal('%s'),\n" "$local_name" >>"$css"
if [ -n "$local_postscript_name" ]; then
printf "\t\tlocal('%s'),\n" "$local_postscript_name" >>"$css"
fi
# For each font format, download the font file and print the corresponding CSS statements.
for uakey in eot woff ttf svg; do
echo -n "$uakey "
# Download Google's CSS and throw some regex at it to find the font's URL
if [ "$uakey" != "svg" ]; then
pattern="http:\\/\\/[^\\)]+\\.$uakey"
else
pattern="http:\\/\\/[^\\)]+"
fi
file=$(curl -sf -A "${useragent[$uakey]}" --get --data-urlencode "family=$family" "$url" | grep -Eo "$pattern" | sort -u)
printf "\t\t/* from %s */\n" "$file" >>"$css"
if [ "$uakey" == "svg" ]; then
# SVG fonts need the font after a hash symbol, so extract the correct name from Google's CSS
svgname=$(echo "$file" | $ESED 's/^[^#]+#(.*)$/\1/g')
fi
# Actually download the font file
curl -sfL "$file" -o "${fontnameescaped}.$uakey"
# Generate the CSS statements required to include the downloaded file.
case "$uakey" in
eot)
printf "\t\turl('%s%s?#iefix') format('embedded-opentype'),\n" "$prefix" "${fontnameescaped}.$uakey" >>"$css"
;;
woff)
printf "\t\turl('%s%s') format('woff'),\n" "$prefix" "${fontnameescaped}.$uakey" >>"$css"
;;
ttf)
printf "\t\turl('%s%s') format('truetype'),\n" "$prefix" "${fontnameescaped}.$uakey" >>"$css"
;;
svg)
printf "\t\turl('%s%s#%s') format('svg');\n" "$prefix" "${fontnameescaped}.${uakey}" "$svgname" >>"$css"
;;
esac
done
printf "}\n" >>"$css"
echo
done
#printf "\t\turl('%s%s#%s') format('svg');\n" "$prefix" "${fontnameescaped}.${uakey}" "$svgname" >>"$css"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment