1
0
mirror of https://github.com/ryanoasis/nerd-fonts.git synced 2024-12-07 17:06:25 +02:00
nerd-fonts/install.sh
Xandor Schiefer 2cf5f12d17 Better installation script
It now has more options than copying all patched files or one font’s
patched font files.

In short, you can choose which patchset, which compatibility, which
method (copy or symlink), and which fonts you want to install.
2016-09-02 10:00:18 +02:00

279 lines
7.8 KiB
Bash
Executable File

#!/bin/bash
# Install Nerd Fonts
__ScriptVersion="0.1"
# Default values for option variables:
quiet=false
mode="copy"
clean=false
mono=false
windows=false
extension="otf"
patches=("Complete")
compat=()
# Usage info
usage() {
cat << EOF
Usage: ./install.sh [-q -v -h] [[--copy | --link] --clean | --list]
[--use-single-width-glyphs] [--windows] [--otf | --ttf]
[--complete | --minimal | <patches>] [FONT...]
General options:
-q, --quiet Suppress output.
-v, --version Print version number and exit.
-h, --help Display this help and exit.
-c, --copy Copy the font files [default].
-l, --link Symlink the font files.
-L, --list List the font files to be installed (dry run).
-C, --clean Recreate the root Nerd Fonts target directory
(clean out all previous copies or symlinks).
-s, --use-single-width-glyphs Install single-width glyphs variants.
-w, --windows Install with limited internal font names.
-O, --otf Prefer OTF font files [default].
-T, --ttf Prefer TTF font files.
Variation to install:
-A, --complete Variants with patches applied [default].
-M, --minimal Variants with minimal patches applied.
If you need more control over the included glyphs than when using the above
two options, use any combination of these <patches>:
--fontawesome Include Font Awesome.
--fontlinux Include Font Linux.
--octicons Include Octicons.
--pomicons Include Pomicons.
EOF
}
# Print version
version() {
echo "Nerd Fonts installer -- Version $__ScriptVersion"
}
# Parse options
optspec=":qvhclLCswOTAM-:"
while getopts "$optspec" optchar; do
case "${optchar}" in
# Short options
q) quiet=true;;
v) version; exit 0;;
h) usage; exit 0;;
c) mode="copy";;
l) mode="link";;
L) mode="list";;
C) clean=true;;
s) compat=( "${compat[@]}" "Nerd Font*Mono" );;
w) compat=( "${compat[@]}" "Windows Compatible" );;
O) extension="otf";;
T) extension="ttf";;
A) patches=("Complete");;
M) patches=();;
-)
case "${OPTARG}" in
# Long options
quiet) quiet=true;;
version) version; exit 0;;
help) usage; exit 0;;
copy) mode="copy";;
link) mode="link";;
list) mode="list";;
clean) clean=true;;
use-single-width-glyphs) compat=( "${compat[@]}" "Nerd Font*Mono" );;
windows) compat=( "${compat[@]}" "Windows Compatible" );;
otf) extension="otf";;
ttf) extension="ttf";;
complete) patches=("Complete");;
minimal) patches=();;
*)
case "${OPTARG}" in
# Long options that define variations
fontawesome | fontlinux | octicons | pomicons)
# If the user has picked one of these options,
# we need to unset `Complete`
delete=("Complete")
patches=( "${patches[@]/$delete}" )
case "${OPTARG}" in
fontawesome) patches=( "${patches[@]}" "Font Awesome" );;
fontlinux) patches=( "${patches[@]}" "Font Linux" );;
octicons) patches=( "${patches[@]}" "Octicons" );;
pomicons) patches=( "${patches[@]}" "Pomicons" );;
esac;;
*)
echo "Unknown option --${OPTARG}" >&2
usage >&2;
exit 1
;;
esac;;
esac;;
*)
echo "Unknown option -${OPTARG}" >&2
usage >&2
exit 1
;;
esac
done
shift $(($OPTIND-1))
# Set source and target directories, default: all fonts
nerdfonts_root_dir="${PWD}/patched-fonts"
nerdfonts_dirs=("$nerdfonts_root_dir")
# Accept font / directory names, to avoid installing all fonts
if [ ! -z "$*" ]; then
nerdfonts_dirs=()
for font in "${@}"; do
if [ ! -z "$font" ]; then
# Ensure that directory exists, and offer suggestions if not
if [[ ! -d "$nerdfonts_root_dir/$font" ]]; then
echo -e "Font $font doesn't exist. Options are: \n"
find "$nerdfonts_root_dir" -maxdepth 1 -type d \( \! -name "$(basename "$nerdfonts_root_dir")" \) -exec basename {} \;
exit -1
fi
nerdfonts_dirs=( "${nerdfonts_dirs[@]}" "$nerdfonts_root_dir/$font" )
fi
done
fi
#
# Start constructing `find` expression
#
implode() {
# $1 is return variable name
# $2 is sep
# $3... are the elements to join
local retname=$1 sep=$2 ret=$3
shift 3 || shift $(($#))
printf -v "$retname" "%s" "$ret${@/#/$sep}"
}
find_include=
find_exclude=
# If we have patches or compat, define what to include
include=()
if [ ! -z "${patches[*]}" ]; then
include=( "${include[@]}" "${patches[@]}" )
fi
if [ ! -z "${compat[*]}" ]; then
include=( "${include[@]}" "${compat[@]}" )
fi
# Delete empty elements
for i in "${!include[@]}"; do
[ "${include[$i]}" = '' ] && unset include[$i]
done
if [ ! -z "${include[*]}" ]; then
implode find_include "*' -and -name '*" "${include[@]}"
find_include="-and -name '*${find_include}*'"
fi
# Exclude everything we didn’t include
exclude=("Complete" "Font Awesome" "Font Linux" "Octicons" "Pomicons" "Nerd Font*Mono" "Windows Compatible")
for delete in "${include[@]}"; do
exclude=( "${exclude[@]/$delete}" )
done
# Delete empty elements
for i in "${!exclude[@]}"; do
[ "${exclude[$i]}" = '' ] && unset exclude[$i]
done
if [ ! -z "${exclude[*]}" ]; then
implode find_exclude "*' -and \! -name '*" "${exclude[@]}"
find_exclude="-and \! -name '*${find_exclude}*'"
fi
# Construct directories to be searched
implode find_dirs "\" \"" "${nerdfonts_dirs[@]}"
find_dirs="\"$find_dirs\""
# Put it all together into the find command we want
find_command="find $find_dirs \( \( -name '*.[o,t]tf' -or -name '*.pcf.gz' \) $find_include $find_exclude \) -type f -print0"
# Find all the font files and store in array
files=()
while IFS= read -r -d $'\0'; do
files+=("$REPLY")
done < <(eval "$find_command")
#
# Remove duplicates (i.e. when both otf and ttf version present)
#
# Get list of file names without extensions
files_dedup=( "${files[@]}" )
for i in "${!files_dedup[@]}"; do
files_dedup[$i]="${files_dedup[$i]%.*}"
done
# Remove duplicates
for i in "${!files_dedup[@]}"; do
for j in "${!files_dedup[@]}"; do
[ $i = $j ] && continue
if [ "${files_dedup[$i]}" = "${files_dedup[$j]}" ]; then
ext="${files[$i]##*.}"
# Only remove if the extension is the one we don’t want
if [ "$ext" != "$extension" ]; then
unset files[$i]
fi
fi
done
done
# Get target root directory
if [[ $(uname) == 'Darwin' ]]; then
# MacOS
font_dir="$HOME/Library/Fonts"
else
# Linux
font_dir="$HOME/.local/share/fonts"
fi
font_dir="${font_dir}/NerdFonts"
#
# Take the desired action
#
case $mode in
list)
for file in "${files[@]}"; do
file=$(basename "$file")
echo "$font_dir/${file#$nerdfonts_root_dir/}"
done
exit 0
;;
copy | link)
if [ "$clean" = true ]; then
[ "$quiet" = false ] && rm -rfv "$font_dir"
[ "$quiet" = true ] && rm -rf "$font_dir"
fi
[ "$quiet" = false ] && mkdir -pv "$font_dir"
[ "$quiet" = true ] && mkdir -p "$font_dir"
case $mode in
copy)
[ "$quiet" = false ] && cp -fv "${files[@]}" "$font_dir"
[ "$quiet" = true ] && cp -f "${files[@]}" "$font_dir"
;;
link)
[ "$quiet" = false ] && ln -sfv "${files[@]}" "$font_dir"
[ "$quiet" = true ] && ln -sf "${files[@]}" "$font_dir"
;;
esac;;
esac
# Reset font cache on Linux
if [[ -n $(which fc-cache) ]]; then
[ "$quiet" = false ] && fc-cache -vf "$font_dir"
[ "$quiet" = true ] && fc-cache -f "$font_dir"
fi