#!/usr/bin/env bash # Shamelessly extract ASCII distro logos from neofetch # (https://github.com/dylanaraps/neofetch) # and convert them into C string constants. # Requires bash for associative arrays, bleh. # Takes a single argument: path to neofetch binary set -e usage () { echo "usage: `basename $0` path-to-neofetch" ; } [ $# -eq 1 ] || { usage >&2 ; return 1 ; } # Obviously, we're very sensitive to the exact contents of the neofetch # script. We rely on: # # ...arbitrary text... # ^get_distro_ascii() {$ # We set STARTED to non-empty upon hitting "get_distro_ascii()" STARTED="" # We set LOGOSTARTED to the line where the current logo starts, and unset it # upon the logo's termination (discovered via ^EOF$). LOGOSTARTED="" LINE=0 LOGOS=0 # don't emit the same key more than once, or we'll get multiple definitions declare -A KEYSSEEN while IFS= read -r line ; do LINE=$((LINE + 1)) if [ -z "$STARTED" ] ; then if [ "$line" = 'get_distro_ascii() {' ] ; then STARTED="$LINE" echo "#include \"ncart.h\"" echo "#include " echo "#include " echo "// Output of \"`basename $0` $1\"" echo "// Generated on `date -u`" echo "// Copyright Dylan Araps under an MIT License" echo "// Found get_distro_ascii at line $LINE" fi elif [ -z "$NAME" ] ; then NAME=`echo "$line" | sed -n -e 's/.*"\([^|]*\)"\*\?)$/\1/p'` if [ -n "$NAME" ] ; then echo "// Logo #$LOGOS: $NAME..." NAME=`echo $NAME | sed -e 's/\\\\/\\\\\\\\/g' | tr \ _ | tr / _ | tr -- - _` if [ -z "${KEYSSEEN[$NAME]}" ] ; then KEYSSEEN[$NAME]="$LINE" PRESERVE="$NAME" else echo "Warning, found duplicate name $NAME" >&2 fi elif [ "$line" = "}" ] ; then # are we done with get_distro_ascii()? DONE="$LINE" echo "// Closed get_distro_ascii at line $LINE" break fi elif [ -z "$LOGOSTARTED" ]; then if echo "$line" | grep '^ *read -rd ' > /dev/null ; then LOGOS=$((LOGOS + 1)) # found the start of a new logo! LOGOSTARTED="$LINE" if [ -n "$PRESERVE" ] ; then echo -n "static const char $NAME[] = \"" fi fi elif [ -n "$LOGOSTARTED" ]; then if [ "$line" = "EOF" ] ; then if [ -n "$PRESERVE" ] ; then echo "\";" echo "// $NAME: $((LINE - LOGOSTARTED)) lines, done at line $LINE." fi LOGOSTARTED="" NAME="" PRESERVE="" else if [ -n "$PRESERVE" ] ; then # FIXME don't eliminate the color templating once we carry colors /bin/echo -E -n "$line" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/${c.}//g' && /bin/echo -E -n '\n' fi fi fi done < "$1" # if DONE is defined, we ran to completion. yay! emit a table providing # access to these strings via key comparison. if [ -n "$DONE" ] ; then echo echo "struct neofetch_art { const char* oskey; const char* ncart; };" echo echo "const struct neofetch_art ncarts[] = {" for k in "${!KEYSSEEN[@]}" ; do echo " { \"$k\", $k }," done echo " { NULL, NULL }" echo "};" echo echo "const char* get_neofetch_art(const char* oskey){" echo " for(const struct neofetch_art* nfa = ncarts ; nfa->oskey ; ++nfa){" echo " if(strcasecmp(nfa->oskey, oskey) == 0){" echo " return nfa->ncart;" echo " }" echo " }" echo " return NULL;" echo "}" exit 0 fi # unsurprisingly, this incredibly brittle code has broken. crap! if [ -z "$STARTED" ] ; then echo "Failed; never found get_distro_ascii(). Alas..." >&2 else echo "Failed; never closed out get_distro_ascii(). Hrmm..." >&2 fi exit 1