My vocabulary list to pdf flashcard Bash script

This script takes a list of words (single column in plain text format) and produces a .pdf with a word and definition each page.

Depends: latex-beamer and Stardict's "sdcv" with the WordNet dictionary in Stardict's directory /usr/share/stardict/dic
(dictionary package also available here: stardict_wordnet.tar.bz2)

Also uses pdfunite, a part of the poppler package (which is a dependancy of CUPS, so should be included in the base install of most distributions); and Zenity for the dialog boxes but also is included in most distros.

(I first used pdftk to combine the resulting .pdf pages but found it was unnecessary.)

vocab2pdf_example.png

example screenshot

Script available here. Put it in your Home's bin directory and set to be executable.
It can be ran outside the terminal (typically using the Alt+F2 Run instead).

The script opens the resulting .pdf in the default viewer when done.


#!/bin/bash
########################## vocab2pdf ##########################
###
# *  (C) 2014-16 - erfahren@atadcrazy.net 
# *  Licensed under GNU General Public License 3.0 or later. 
# *  Some rights reserved. See COPYING, AUTHORS.
# * @license GPL-3.0+ http://spdx.org/licenses/GPL-3.0+
#
# dependencies: latex-beamer, poppler's pdfunite, sdcv (with WordNet dictionary)
# WordNet dictionary in Stardict's directory /usr/share/stardict/dic
# package available at http://abloz.com/huzheng/stardict-dic/dict.org/
# for more info visit: https://owenh.net/stardict.html
###
# script includes the option to format the list in alphabetical order and remove duplicates
###
cd $(pwd)
zenity --info --title="vocab2pdf" --text="This script prompts for a plain text file containing \
                                          \na single column list of words in  to be processed."
# Zenity File Selector
FILE=`zenity --file-selection --width=600 --height=400 --title="Select a plain text file with list of words"`

case $? in
         0)
                echo "\"$FILE\" selected.";;
         1)
                echo "No file selected.";;
        -1)
                echo "An unexpected error has occurred.";;
esac

cat $FILE | awk '{print $1}' > $FILE.tmp && mv $FILE.tmp $FILE #| zenity --progress \
                                                                #--pulsate --auto-close \
                                                                #--title="Working... please wait"
# the commented out 'zenity --progress' above may not be needed/wanted ^

########################## SORT ##########################

zenity --question --text="Sort the list? (creates backup of the orginal) \ 
                          \n *sorts in alphabetical order \
                          \n *removes duplicates" --ok-label="Yes" --cancel-label="No"; echo $?

if [ $? = 0 ]; then
cp $FILE $FILE.back && sort -b -d $FILE > $FILE-srtd && uniq -u $FILE-srtd > $FILE-srtd-nodupes && sed '/^\s*$/d' $FILE-srtd-nodupes > $FILE-srtd && mv $FILE-srtd $FILE && rm $FILE-srtd-nodupes

else
    $FILE=$FILE
fi

##########################################################
mkdir -p ./vocabtmp
cd ./vocabtmp
cat $FILE | while read line
 do
 sdcv -n -u "WordNet" $line > ./defwordtmp1
cat ./defwordtmp1 | sed '1,4d' > ./defwordtmp2
## ensuring word was found and... ##
## setting the first word out of the results as the variable "entryword"
entryword=$(awk 'NR == 1 { print $1 }' ./defwordtmp2)
if [ "$entryword" == "$line" ]
then
sed '/^$/d' ./defwordtmp2 > ./defwordtmp1
sed 10q ./defwordtmp1 > defwordtextmp 
## above removes blank lines and cuts definition to ten lines
###
### PREPARE TEX FILES ###
###
mkdir -p ./texfiles
echo "\documentclass[a5paper]{book}" > ./texfiles/"$entryword".tex
echo "\usepackage[usenames,dvipsnames]{xcolor}" >> ./texfiles/"$entryword".tex
echo "\definecolor{darkblue}{RGB}{24,24,72}" >> ./texfiles/"$entryword".tex
echo "\usepackage[landscape,margin=1.0cm]{geometry}" >> ./texfiles/"$entryword".tex
echo "\usepackage[latin1]{inputenc}" >> ./texfiles/"$entryword".tex
echo "\usepackage{tikz}" >> ./texfiles/"$entryword".tex
echo "\usetikzlibrary{shapes,decorations}" >> ./texfiles/"$entryword".tex
echo "\pagecolor{darkblue}" >> ./texfiles/"$entryword".tex
echo "\begin{document}" >> ./texfiles/"$entryword".tex
echo "\tikzstyle{mybox} = [draw=blue, fill=blue!10, very thick," >> ./texfiles/"$entryword".tex
echo "   rectangle, rounded corners, inner sep=48pt, inner ysep=64pt]" >> ./texfiles/"$entryword".tex
echo "\tikzstyle{fancytitle} =[fill=blue, text=white, ellipse]" >> ./texfiles/"$entryword".tex
echo "\begin{tikzpicture}[transform shape, baseline=-3.5cm]" >> ./texfiles/"$entryword".tex
echo "\tikzstyle{every node}=[font=\LARGE]" >> ./texfiles/"$entryword".tex
echo "\node [mybox] (box) {%" >> ./texfiles/"$entryword".tex
echo "   \begin{minipage}[t!]{.75\textwidth}" >> ./texfiles/"$entryword".tex
## inserting the definition from defwordtextmp ##
cat ./defwordtextmp >> ./texfiles/"$entryword".tex
echo "   \end{minipage}" >> ./texfiles/"$entryword".tex
echo "   };" >> ./texfiles/"$entryword".tex
## entryword inserted here for north box ##
echo "\node[fancytitle] at (box.north) {$entryword};" >> ./texfiles/"$entryword".tex
echo "\end{tikzpicture}" >> ./texfiles/"$entryword".tex
echo "\end{document}" >> ./texfiles/"$entryword".tex
###
### DONE CREATING TEX FILES ###
###
else
echo -e $line >> ../vocab-notfound.log
fi
done
###
### CREATING PDF's ###
#zenity --info --title="Info" --text="Now creating pdf, \n\n  please wait..."
###
cd ./texfiles
for i in *.tex; do
if [ -e "$i" ]; then
   file=`basename "$i" .tex`
pdflatex "$file.tex" 
fi
done | zenity --progress --pulsate --title="Working... " \
                                   --text="Creating pdf, \n  please wait..."
### COMBINING PDF's ###
# pdftk *.pdf cat output ../../vocab-all.pdf
pdfunite $(ls *.pdf) ../../vocab-all.pdf 
# combined pdfs into vocab-all.pdf
zenity --info --title="Info" --text="words not found logged in vocab-notfound.log"
cd ../../
## cleanup ##
rm -r ./vocabtmp
#evince ./vocab-all.pdf &
# open resulting .pdf in default application
xdg-open ./vocab-all.pdf &

exit 0




Back to Top