Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various enhancements / fixes #56

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ configure them using environment variables.
- `xdotool`
- `fzf`
- `imagemagick`
- `nsxiv`
- `nsxiv`, `sxiv`, or `feh`

## Installation
### Install using `make`
Expand Down
180 changes: 115 additions & 65 deletions fontpreview
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,41 @@
#
# Siddharth Dushantha 2020
#
# Dependencies: nsxiv, imagemagick, xdotool, fzf
# Dependencies: nsxiv, sxiv, or feh, and imagemagick, xdotool, fzf

exec 3>&2 # save a copy of original stderr for fzf to use
# uncomment next line to save a debug trace
# exec 2>/tmp/fontpreview.log ; set -x

VERSION=1.0.7

# Default values
SEARCH_PROMPT="❯ "
SIZE=1000x1000
POSITION="+0+0"
SIZE=530x730
POSITION=; # Let the window manager choose a position. User can override.
FONT_SIZE=38
BG_COLOR="#ffffff"
FG_COLOR="#000000"
PREVIEW_TEXT="ABCDEFGHIJKLM\nNOPQRSTUVWXYZ\nabcdefghijklm\nnopqrstuvwxyz\n1234567890\n!@$\%(){}[]\nالسلام عليكم"
PREVIEW_HEADER=true
PREVIEW_TEXT='\
ABCDEFGHIJKLM\n\
NOPQRSTUVWXYZ\n\
abcdefghijklm\n\
nopqrstuvwxyz\n\
1234567890\n\
!@$\\/%%(){}[]\n\
.,:;=+>--<__\n\
({[ -~\n\
DO08B 1Ili\n\
AR 9gq oa\n\
السلام عليكم \
'

show_help() {
printf "%s" "\
usage: fontpreview [-h] [--size \"px\"] [--position \"+x+y\"] [--search-prompt SEARCH_PROMPT]
[--font-size \"FONT_SIZE\"] [--bg-color \"BG_COLOR\"] [--fg-color \"FG_COLOR\"]
[--preview-text \"PREVIEW_TEXT\"] [-i font.otf] [-o preview.png] [--version]
[--preview-text \"PREVIEW_TEXT\"] [--preview-header yes/no] [-i font.otf] [-o preview.png] [--version]

┌─┐┌─┐┌┐┌┌┬┐┌─┐┬─┐┌─┐┬ ┬┬┌─┐┬ ┬
├┤ │ ││││ │ ├─┘├┬┘├┤ └┐┌┘│├┤ │││
Expand All @@ -37,43 +54,59 @@ optional arguments:
--bg-color background color of the font preview window
--fg-color foreground color of the font preview window
--preview-text preview text that should be displayed in the font preview window
--preview-header include the font name in the preview image
--version show the version of fontpreview you are using
"
}

pre_exit() {
# Get the proccess ID of this script and kill it.
# We are dumping the output of kill to /dev/null
# because if the user quits nsxiv before they
# exit this script, an error will be shown
# from kill and we dont want that
kill -9 "$(cat "$PIDFILE" 2>/dev/null)" &> /dev/null
# kill the image viewer
test "$viewerpid" && kill -TERM $viewerpid 2>/dev/null

# Delete tempfiles, so we don't leave useless files behind.
rm -rf "$FONTPREVIEW_DIR"
}

wrapfontname()
{
if [[ -f "$1" ]]
then # if it's a filename, just fold the basename
fold -w 20 <<<"${1##*/}"
else # otherwise, change '-' to space and wrap on spaces
sed -e 's/-/ /g' <<<"$1" | fold -s -w 20
fi
}

generate_preview(){

fontspec=$1
outpng=$2

[[ $PREVIEW_HEADER == true ]] &&
header="$(wrapfontname $fontspec)\n\n"

# Credits: https://bit.ly/2UvLVhM
magick -size $SIZE xc:"$BG_COLOR" \
$magick -size $SIZE xc:"$BG_COLOR" \
-gravity center \
-pointsize $FONT_SIZE \
-font "$1" \
-font "$fontspec" \
-fill "$FG_COLOR" \
-annotate +0+0 "$PREVIEW_TEXT" \
-flatten "$2"
-annotate +0+0 \
"$header$PREVIEW_TEXT" \
"$outpng.tmp.png" &&
mv "$outpng.tmp.png" "$outpng"
}

main(){
# Checkig if needed dependencies are installed
dependencies=(xdotool nsxiv magick fzf)
for dependency in "${dependencies[@]}"; do
type -p "$dependency" &>/dev/null || {
echo "error: Could not find '${dependency}', is it installed?" >&2
exit 1
}
done
error(){
echo fontpreview error: "$@" >&2
exit 1
}

exists(){
type -p "$1" &>/dev/null
}

initialize(){
# Checking for enviornment variables which the user might have set.
# This config file for fontpreview is pretty much the bashrc, zshrc, etc
# Majority of the variables in fontpreview can changed using the enviornment variables
Expand All @@ -85,61 +118,70 @@ main(){
[[ $FONTPREVIEW_BG_COLOR != "" ]] && BG_COLOR=$FONTPREVIEW_BG_COLOR
[[ $FONTPREVIEW_FG_COLOR != "" ]] && FG_COLOR=$FONTPREVIEW_FG_COLOR
[[ $FONTPREVIEW_PREVIEW_TEXT != "" ]] && PREVIEW_TEXT=$FONTPREVIEW_PREVIEW_TEXT
[[ $FONTPREVIEW_HEADER != "" ]] && PREVIEW_HEADER=$FONTPREVIEW_HEADER

# Checking if needed dependencies are installed
if exists nsxiv
then
viewer=nsxiv
# -N sets the X11 resource class name, not the title
vieweropts=( -N "fontpreview" -b -g "$SIZE$POSITION" "$FONT_PREVIEW")
elif exists sxiv
then
viewer=sxiv
vieweropts=( -N "fontpreview" -b -g "$SIZE$POSITION" "$FONT_PREVIEW")
elif exists feh
then
viewer=feh
vieweropts=( --title "fontpreview" -g "$SIZE$POSITION" "$FONT_PREVIEW")
fi
test "$viewer" || error None of nsxiv, sxiv, or feh is available.

exists convert && magick=convert
exists magick && magick=magick
test "$magick" || error Neither magick nor convert is available.

exists xdotool || error xdotool not available
exists fzf || error fzf not available

}

start_viewer(){

$viewer ${vieweropts[@]} &
}

main(){
# Save the window ID of the terminal window fontpreview is executed in.
# This is so that when we open up nsxiv, we can change the focus back to
# the terminal window, so that the user can search for the fonts without
# having to manualy change the focus back to the terminal.
xdotool getactivewindow > "$TERMWIN_IDFILE"

# Flag to run some commands only once in the loop
FIRST_RUN=true

while true; do
# List out all the fonts which imagemagick is able to find, extract
# the font names and then pass them to fzf
font=$(magick -list font | awk -F: '/^[ ]*Font: /{print substr($NF,2)}' | fzf --prompt="$SEARCH_PROMPT")
font=$($magick -list font |
awk -F: '/^[ ]*Font: /{print substr($NF,2)}' |
fzf --query=$(cat $FONTPREVIEW_DIR/query 2>/dev/null) \
--preview="echo {q} > $FONTPREVIEW_DIR/query" \
--prompt="$SEARCH_PROMPT" 2>&3)

# Exit if nothing is returned by fzf, which also means that the user
# has pressed [ESCAPE]
[[ -z $font ]] && return

generate_preview "$font" "$FONT_PREVIEW"

if [[ $FIRST_RUN == true ]]; then
FIRST_RUN=false

# Display the font preview using nsxiv
#nsxiv -g "$SIZE$POSITION" "$FONT_PREVIEW" -N "fontpreview" -b &
nsxiv -N "fontpreview" -b -g "$SIZE$POSITION" "$FONT_PREVIEW" &
if [[ ! $viewerpid ]] || ! kill -0 $viewerpid 2>/dev/null; then
start_viewer
viewerpid=$!

# Change focus from nsxiv, back to the terminal window
# so that user can continue to search for fonts without
# having to manually change focus back to the terminal window
xdotool windowfocus "$(cat "$TERMWIN_IDFILE")"

# Save the process ID so that we can kill
# nsxiv when the user exits the script
echo $! >"$PIDFILE"

# Check for crashes of nsxiv
elif [[ -f $PIDFILE ]] ; then
if ! pgrep -F "$PIDFILE" >/dev/null 2>&1; then
echo "Restart nsxiv - You maybe using a obsolete version. " >&2
# Display the font preview using nsxiv
nsxiv -g "$SIZE$POSITION" -N "fontpreview" -b "$FONT_PREVIEW" &

# Change focus from nsxiv, back to the terminal window
# so that user can continue to search for fonts without
# having to manually change focus back to the terminal window
xdotool windowfocus "$(cat "$TERMWIN_IDFILE")"

# Save the process ID so that we can kill
# nsxiv when the user exits the script
echo $! >"$PIDFILE"
fi

fi
fi
done
}

Expand All @@ -153,18 +195,17 @@ trap pre_exit EXIT
# Use mktemp to create a temporary directory that won't
# collide with temporary files of other application.
FONTPREVIEW_DIR="$(mktemp -d "${TMPDIR:-/tmp}/fontpreview_dir.XXXXXXXX")" || exit
PIDFILE="$FONTPREVIEW_DIR/fontpreview.pid"
touch "$PIDFILE" || exit
FONT_PREVIEW="$FONTPREVIEW_DIR/fontpreview.png"
touch "$FONT_PREVIEW" || exit
TERMWIN_IDFILE="$FONTPREVIEW_DIR/fontpreview.termpid"
touch "$TERMWIN_IDFILE" || exit

font=$1


# Parse the arguments
options=$(getopt -o hi:o: --long position:,size:,version,search-prompt:,font-size:,bg-color:,fg-color:,preview-text:,input:,output:,help -- "$@")
options=$(getopt -o hi:o: --long position:,size:,version,search-prompt:,font-size:,bg-color:,fg-color:,preview-text:,preview-header:,input:,output:,help -- "$@")
# exit on usage errors
[[ $? == 0 ]] || error "try -h for help"

eval set -- "$options"

while true; do
Expand Down Expand Up @@ -206,6 +247,12 @@ while true; do
--preview-text)
FONTPREVIEW_PREVIEW_TEXT=$2
;;
--preview-header)
case $2 in
[yYtT1]*) FONTPREVIEW_HEADER=true ;;
[nNfF0]*) FONTPREVIEW_HEADER=false; ;;
esac
;;
--)
shift
break
Expand All @@ -214,6 +261,9 @@ while true; do
shift
done

initialize

font=$1

# Point a font file to fontpreview and it will preview it.
# Example:
Expand All @@ -225,10 +275,10 @@ done
if [ -f "$font" ]; then
generate_preview "$font" "$FONT_PREVIEW"

# Display the font preview using nsxiv
nsxiv -g "$SIZE$POSITION" -N "fontpreview" -b "$FONT_PREVIEW" &
start_viewer
# don't set viewerpid, else it will be killed when we exit

# For some strange reason, nsxiv just doesnt have time to read the file
# exit will remove the file, so give nsxiv time to read it first
sleep 0.1
exit
fi
Expand Down