notcurses/tools/neofetch-ripper
2021-02-03 00:43:15 -05:00

142 lines
4.5 KiB
Bash
Executable File

#!/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 ; exit 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"
# FIXME copy the copyright directly from neofetch?
cat << EOHEADER
#include "ncart.h"
#include <stdlib.h>
#include <strings.h>
// Output of "`basename $0` $1"
// Generated on `date -u`
// Copyright Dylan Araps under an MIT License
// The MIT License (MIT)
//
// Copyright (c) 2015-2021 Dylan Araps
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// Found get_distro_ascii at line $LINE
EOHEADER
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