1#!/usr/bin/env bash 2# Nerd Fonts Version: 2.1.0 3# Script Version: 1.1.1 4 5 # used for debugging 6 #set -x 7 8# for executing script to rebuild JUST the readmes: 9# ./gotta-patch-em-all-font-patcher\!.sh "" info 10 11LINE_PREFIX="# [Nerd Fonts] " 12 13# Check for Fontforge 14type fontforge >/dev/null 2>&1 || { 15 echo >&2 "$LINE_PREFIX FontForge must be installed before running this script." 16 echo >&2 "# Please see installation instructions at" 17 echo >&2 "# http://designwithfontforge.com/en-US/Installing_Fontforge.html" 18 exit 1 19} 20 21res1=$(date +%s) 22parent_dir="${PWD}/../../" 23# Set source and target directories 24source_fonts_dir="${PWD}/../../src/unpatched-fonts" 25like_pattern='' 26complete_variations_per_family=4 27font_typefaces_count=0 28font_families_count=0 29complete_variation_count=0 30total_variation_count=0 31total_count=0 32last_parent_dir="" 33unpatched_parent_dir="bin/scripts/../../src/unpatched-fonts" 34patched_parent_dir="patched-fonts" 35max_parallel_process=64 36 37if [ $# -eq 1 ] 38 then 39 like_pattern=$1 40 echo "$LINE_PREFIX Parameter given, limiting search and patch to pattern '$like_pattern' given" 41fi 42 43# simple second param option to allow to regenerate font info without re-patching 44if [ $# -eq 2 ] 45 then 46 info_only=$2 47 echo "$LINE_PREFIX 'Info Only' Parameter given, only generating font info (not patching)" 48fi 49 50# correct way to output find results into an array (when files have space chars, etc) 51# source: https://stackoverflow.com/questions/8213328/bash-script-find-output-to-array 52source_fonts=() 53 while IFS= read -d $'\0' -r file ; do 54 source_fonts=("${source_fonts[@]}" "$file") 55 done < <(find "$source_fonts_dir" -iname "$like_pattern*.[o,t]tf" -type f -print0) 56 57# print total number of source fonts found 58echo "$LINE_PREFIX Total source fonts found: ${#source_fonts[*]}" 59 60 61function patch_font { 62 local f=$1; shift 63 local i=$1; shift 64 #echo $i 65 #echo $f 66 # take everything before the last slash (/) to start building the full path 67 local patched_font_dir="${f%/*}/" 68 # find replace unpatched parent dir with patched parent dir: 69 local patched_font_dir="${patched_font_dir/$unpatched_parent_dir/$patched_parent_dir}" 70 71 [[ -d "$patched_font_dir" ]] || mkdir -p "$patched_font_dir" 72 73 config_parent_dir=$( cd "$( dirname "$f" )" && cd ".." && pwd) 74 config_dir=$( cd "$( dirname "$f" )" && pwd) 75 76 # source the font config file if exists: 77 if [ -f "$config_dir/config.cfg" ] 78 then 79 # shellcheck source=/dev/null 80 source "$config_dir/config.cfg" 81 elif [ -f "$config_parent_dir/config.cfg" ] 82 then 83 # shellcheck source=/dev/null 84 source "$config_parent_dir/config.cfg" 85 fi 86 87 if [ -f "$config_parent_dir/config.json" ] 88 then 89 # load font configuration file and remove ligatures (for mono fonts): 90 font_config="--removeligatures --configfile $config_parent_dir/config.json" 91 else 92 font_config="" 93 fi 94 95 if [ "$post_process" ] 96 then 97 post_process="--postprocess=$post_process" 98 else 99 post_process="" 100 fi 101 102 # shellcheck disable=SC2154 103 # we know the '$config_has_powerline' is from the sourced file 104 if [ "$config_has_powerline" ] 105 then 106 powerline="" 107 combinations=$(printf "./font-patcher ${f##*/} %s\\n" {' --use-single-width-glyphs',}{' --windows',}{' --fontawesome',}{' --octicons',}{' --fontlinux',}{' --pomicons',}{' --powerlineextra',}{' --fontawesomeextension',}{' --powersymbols',}{' --weather',}{' --material',}) 108 else 109 powerline="--powerline" 110 combinations=$(printf "./font-patcher ${f##*/} %s\\n" {' --powerline',}{' --use-single-width-glyphs',}{' --windows',}{' --fontawesome',}{' --octicons',}{' --fontlinux',}{' --pomicons',}{' --powerlineextra',}{' --fontawesomeextension',}{' --powersymbols',}{' --weather',}{' --material',}) 111 fi 112 113 cd "$parent_dir" || { 114 echo >&2 "# Could not find project parent directory" 115 exit 1 116 } 117 118 fontforge -quiet -script ./font-patcher "$f" -q $powerline $post_process --complete --no-progressbars --outputdir "${patched_font_dir}complete/" 2>/dev/null 119 fontforge -quiet -script ./font-patcher "$f" -q -s ${font_config} $powerline $post_process --complete --no-progressbars --outputdir "${patched_font_dir}complete/" 2>/dev/null 120 fontforge -quiet -script ./font-patcher "$f" -q -w $powerline $post_process --complete --no-progressbars --outputdir "${patched_font_dir}complete/" 2>/dev/null 121 fontforge -quiet -script ./font-patcher "$f" -q -s ${font_config} -w $powerline $post_process --complete --no-progressbars --outputdir "${patched_font_dir}complete/" 2>/dev/null 122 # wait for this group of background processes to finish to avoid forking too many processes 123 # that can add up quickly with the number of combinations 124 #wait 125 126} 127 128function generate_info { 129 local f=$1; shift 130 local i=$1; shift 131 #echo $i 132 #echo $f 133 # take everything before the last slash (/) to start building the full path 134 local patched_font_dir="${f%/*}/" 135 # find replace unpatched parent dir with patched parent dir: 136 local patched_font_dir="${patched_font_dir/$unpatched_parent_dir/$patched_parent_dir}" 137 138 [[ -d "$patched_font_dir" ]] || mkdir -p "$patched_font_dir" 139 140 config_parent_dir=$( cd "$( dirname "$f" )" && cd ".." && pwd) 141 config_dir=$( cd "$( dirname "$f" )" && pwd) 142 config_parent_dir_name=$(basename "$config_parent_dir") 143 is_unpatched_fonts_root=0 144 145 if [ "$config_parent_dir_name" == "unpatched-fonts" ] 146 then 147 is_unpatched_fonts_root=1 148 font_typefaces_count=$((font_typefaces_count+1)) 149 fi 150 151 # source the font config file if exists: 152 if [ -f "$config_dir/config.cfg" ] 153 then 154 # shellcheck source=/dev/null 155 source "$config_dir/config.cfg" 156 elif [ -f "$config_parent_dir/config.cfg" ] 157 then 158 # shellcheck source=/dev/null 159 source "$config_parent_dir/config.cfg" 160 fi 161 162 if [ "$config_has_powerline" ] 163 then 164 powerline="" 165 combinations=$(printf "./font-patcher ${f##*/} %s\\n" {' --use-single-width-glyphs',}{' --windows',}{' --fontawesome',}{' --octicons',}{' --fontlinux',}{' --pomicons',}{' --powerlineextra',}{' --fontawesomeextension',}{' --powersymbols',}{' --weather',}{' --material',}) 166 else 167 powerline="--powerline" 168 combinations=$(printf "./font-patcher ${f##*/} %s\\n" {' --powerline',}{' --use-single-width-glyphs',}{' --windows',}{' --fontawesome',}{' --octicons',}{' --fontlinux',}{' --pomicons',}{' --powerlineextra',}{' --fontawesomeextension',}{' --powersymbols',}{' --weather',}{' --material',}) 169 fi 170 171 font_families_count=$((font_families_count+1)) 172 complete_variation_count=$((complete_variation_count+complete_variations_per_family)) 173 combination_count=$(printf "%s" "$combinations" | wc -l) 174 175 # generate the readmes: 176 177 # if first time with this font then re-build parent dir readme, else skip: 178 if [[ $config_parent_dir != "$last_parent_dir" ]] && [ $is_unpatched_fonts_root == "0" ]; 179 then 180 echo "$LINE_PREFIX Re-generate parent directory readme" 181 generate_readme "$patched_font_dir.." 0 182 fi 183 184 generate_readme "$patched_font_dir" 1 185 186 last_parent_dir=$config_parent_dir 187 188 total_variation_count=$((total_variation_count+combination_count)) 189 total_count=$((total_count+complete_variations_per_family+combination_count)) 190 191} 192 193# Re-generate all the readmes 194# $1 = fontdir path 195function generate_readme { 196 local patched_font_dir=$1 197 local generate_combinations=$2 198 local combinations_filename="$patched_font_dir/readme.md" 199 local font_info="$patched_font_dir/font-info.md" 200 201 # clear output file (needed for multiple runs or updates): 202 true > "$combinations_filename" 203 204 if [ -f "$font_info" ]; 205 then 206 cat "$patched_font_dir/font-info.md" >> "$combinations_filename" 207 else 208 echo "$LINE_PREFIX Could not append font-info.md (file not found). Was standardize script run? It should be executed first" 209 echo "# looked for: $font_info" 210 fi 211 212 cat "$parent_dir/src/readme-per-directory-variations.md" >> "$combinations_filename" 213 214 if [ "$generate_combinations" == 1 ]; 215 then 216 echo "$LINE_PREFIX Adding 'Possible Combinations' section" 217 # add to the file 218 { 219 printf "\`\`\`sh" 220 printf "\\n# %s Possible Combinations:\\n" "$combination_count" 221 printf "\\n" 222 printf "%s" "$combinations" 223 printf "\\n" 224 printf "\`\`\`" 225 } >> "$combinations_filename" 226 fi 227} 228 229if [ ! "$info_only" ] 230then 231 # Iterate through source fonts 232 for i in "${!source_fonts[@]}" 233 do 234 patch_font "${source_fonts[$i]}" "$i" 2>/dev/null & 235 236 # un-comment to test this script (patch 1 font) 237 #break 238 239 # wait for this set of bg commands to finish: dont do too many at once! 240 # if we spawn a background process for each set of fonts it will 241 # end up using too many system resources 242 # however we want to run a certain number in parallel to decrease 243 # the amount of time patching all the fonts will take 244 # for now set a 'wait' for each X set of processes: 245 if [[ $((i % max_parallel_process)) == 0 ]]; 246 then 247 echo "$LINE_PREFIX Complete Variation Count after max parallel process is $complete_variation_count" 248 wait 249 fi 250 done 251 # wait for all bg commands to finish 252 wait 253fi 254 255# update information in separate iteration (to avoid issues with bg processes and the counts): 256# Iterate through source fonts 257for i in "${!source_fonts[@]}" 258do 259 # only output after last slash (/): 260 path=${source_fonts[$i]} 261 font_file=${path##*/} 262 echo "$LINE_PREFIX Generating info for '$font_file'" 263 generate_info "$path" "$i" 2>/dev/null 264done 265 266font_typefaces_count=$(find "${PWD}/../../${patched_parent_dir}/"* -maxdepth 0 -type d | wc -l) 267 268res2=$(date +%s) 269dt=$(echo "$res2 - $res1" | bc) 270dd=$(echo "$dt/86400" | bc) 271dt2=$(echo "$dt-86400*$dd" | bc) 272dh=$(echo "$dt2/3600" | bc) 273dt3=$(echo "$dt2-3600*$dh" | bc) 274dm=$(echo "$dt3/60" | bc) 275ds=$(echo "$dt3-60*$dm" | bc) 276 277printf "$LINE_PREFIX Total runtime: %d:%02d:%02d:%02d\\n" "$dd" "$dh" "$dm" "$ds" 278 279printf "# All fonts patched to sub-directories in \\t\\t\\t'%s'\\n" "$patched_parent_dir" 280printf "# The total number of font typefaces patched was \\t\\t'%s'\\n" "$font_typefaces_count" 281printf "# The total number of font families patched was \\t\\t'%s'\\n" "$font_families_count" 282printf "# The total number of 'complete' patched fonts created was \\t'%s'\\n" "$complete_variation_count" 283printf "# The total number of 'variation' patched fonts created was \\t'%s'\\n" "$total_variation_count" 284printf "# The total number of patched fonts created was \\t\\t'%s'\\n" "$total_count" 285