audiogame-manager/speech/clipboard_translator.sh

78 lines
2.6 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# Modified from the script at:
# https://gist.github.com/fdietze/6768a0970d7d732b7fbd7930ccceee2a
set -Eeuo pipefail # https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/#:~:text=set%20%2Du,is%20often%20highly%20desirable%20behavior.
shopt -s expand_aliases
if [[ $# -ne 2 ]]; then
echo "Usage: $0 \"application name\" \"file name\"."
exit 1
fi
# Wait for the application to start
while ! pgrep -u "$USER" ^$1 &> /dev/null ; do
sleep 0.05
done
fileName="${2,,}"
fileName="${fileName//[[:space:]]/-}.sqlite"
translationFile="${XDG_CACHE_HOME:-$HOME/.cache}/audiogame-manager/${fileName}"
# Read so long as the application is running
while pgrep -u "$USER" ^$1 &> /dev/null ; do
sleep 0.05
text="$(xclip -d "${DISPLAY:-:0}" -selection clipboard -o 2> /dev/null)"
if [[ "${text}" =~ ^[0-9A-Za-z[:space:][:punct:]]+$ ]]; then
spd-say -- "$text"
echo "" | xclip -d "${DISPLAY:-:0}" -selection clipboard 2> /dev/null
continue
fi
if [[ -z "$text" ]]; then
continue
fi
q() { sqlite3 -column -init "" "$translationFile" "$@" 2> /dev/null ; }
if [[ ! -s "$translationFile" ]]; then
rm -f "$translationFile"
cat << EOF | sqlite3 -init "" "$translationFile" 2> /dev/null
.bail on
CREATE TABLE translations(
text TEXT NOT NULL,
translation TEXT NOT NULL,
PRIMARY KEY (text)
);
CREATE INDEX translations_text_idx ON translations (text);
EOF
fi
# https://en.wikipedia.org/wiki/Unicode_equivalence#Combining_and_precomposed_characters
# https://www.effectiveperlprogramming.com/2011/09/normalize-your-perl-source/
alias nfc="perl -MUnicode::Normalize -CS -ne 'print NFC(\$_)'" # composed characters
# Normalize different unicode space characters to the same space
# https://stackoverflow.com/a/43640405
alias normalize_spaces="perl -CSDA -plE 's/[^\\S\\t]/ /g'"
alias normalize_unicode="normalize_spaces | nfc"
textEscaped="$(echo "$text" | sed "s/'/''/g" | normalize_unicode)" # escape single quotes for sqlite
translated="$(q "SELECT translation FROM translations WHERE text = '$textEscaped' LIMIT 1" | sed 's/\s*$//')"
if [[ -z "$translated" ]]; then
translated="$(trans -no-autocorrect -no-warn -brief "$text" | head -1 | sed 's/\s*$//' | normalize_unicode)"
if [[ -n "$translated" ]]; then
translatedEscaped="$(echo "$translated" | sed "s/'/''/g")"
q "INSERT OR IGNORE INTO translations (text, translation) VALUES ('$textEscaped', '$translatedEscaped')"
fi
fi
spd-say -- "$translated"
echo "" | xclip -d "${DISPLAY:-:0}" -selection clipboard 2> /dev/null
done