PDF Printing
PDF Printing
While many applications offer exporting output to portable document format (PDF) files, many others do not. It is easy to add a virtual PDF printer to CUPS by installing the cups-pdf package that is available at http://www.slackbuilds.org
This works well for single documents, but if you print multiple documents that are parsed as having the same name then the older documents will be overwritten. A solution to this is to run a script that watches for the creation of the PDF document in the spool directory (/var/spool/cups-pdf/<username> by default) and then moves the document to another directory (USERS_DIR). The script below (watch_for_spooled_pdf.sh kept in /home/xx/pdf_printing) also prepends a date and time string to keep the document names unique. A user xx should start this script as a background process i.e. /home/xx/pdf_printing/watch_for_spooled_pdf.sh &
#!/bin/sh # Script to watch for creation of .pdf files by CUPS-PDF in spool directory # and move to users directory prepending the creation date and time. # # This script uses the -m option to inotifywait and should never exit. SPOOL_DIR=/var/spool/cups-pdf/xx/ USERS_DIR=/home/xx/Desktop/PDF_Files/ inotifywait -mq --timefmt '%Y%m%d %H%M%S' --format '%T %f' \ -e close_write $SPOOL_DIR \ | while read date time file; do mv $SPOOL_DIR${file} $USERS_DIR${date}${time}_${file} done
What if printed PDF documents should be combined into one large PDF document? A user could move the files to be combined to a new subdirectory and then run the script (combine.sh) shown below. This script creates a single PDF document with bookmark entries to each of the individual documents using the facilities in the pdfpages and hyperref packages of LaTeX. The page order is in the order of creation date and time.
#!/bin/sh # Script to combine .pdf files # Intended to be run from within a directory containing files to be concatenated. # The directory name is accepted as a parameter # First create a .tex file for processing using pdflatex OUTFILE=out2.tex BKMK_TEXT=Contents BKMK_ANCHOR=Beginning BKMK_LEVEL=0 # If the directory name has been passed, then make it the working directory. if [[ $1 ]]; then cd $1; fi echo "\documentclass{article}" > $OUTFILE echo "\usepackage{pdfpages}" >> $OUTFILE echo "\usepackage[bookmarksopen]{hyperref}" >> $OUTFILE echo "\begin{document}" >> $OUTFILE echo "\pdfbookmark["$BKMK_LEVEL"]{"$BKMK_TEXT"}{"$BKMK_ANCHOR"}" >> $OUTFILE BKMK_LEVEL=1 for FILENAME in $( ls ./*.pdf ); do # Create the text to be used in the bookmark entry. # NB. Need to substitute 'space' for 'underscore' to be valid bookmark text. BKMK_TEXT=$(echo $FILENAME | cut -b1-17 --complement | sed s/_/\ /g | sed s/\.pdf$//g) # Create a unique anchor point based on date and time prepended to filename BKMK_ANCHOR=$(echo $FILENAME | cut -b3-16) echo "\pdfbookmark["$BKMK_LEVEL"]{"$BKMK_TEXT"}{"$BKMK_ANCHOR"}" >> $OUTFILE echo "\includepdf[pages=-,fitpaper]{"$FILENAME"}" >> $OUTFILE done echo "\end{document}" >> $OUTFILE # Now process the .tex file # Do a second run so that bookmark entries are resolved pdflatex $OUTFILE; pdflatex $OUTFILE wait # Rename the created .pdf file mv $(basename $OUTFILE .tex).pdf $(date +%Y%m%d%H%M%S)_All.pdf # Cleanup files left by pdflatex processing rm $(basename $OUTFILE .tex)* # Cleanup trigger file if this script has been started from watch_for_combine_start.sh script if [ -f combine.start ]; then rm combine.start; fi # Remove this script rm $0
As a convenience, the user could also have a second background process running the script (watch_for_combine_start.sh) shown below. This script watches for the creation of a 'trigger' file (combine.start) in the directory tree and then executes the 'combine.sh' script shown above. This is useful in a network environment, so that a Windows user manipulating the files via a Samba share can create the combined PDF file without having to log in to the Slackware Linux server.
#!/bin/sh # Script to watch for creation of a trigger file in a directory tree. # This event causes another script to be copied into the tree subdirectory and run. # The tree subdirectory name is passed as a parameter. # # This script should never exit WATCH_DIR=/home/xx/Desktop/PDF_Files TRIGGER_FILE=combine.start SCRIPT_FILE=/home/xx/pdf_printing/combine.sh inotifywait -mqr --timefmt '%Y%m%d %H%M%S' --format '%T %w %f' \ -e close_write $WATCH_DIR \ | while read date time path file; do if [ ${file} == $TRIGGER_FILE ]; then cp $SCRIPT_FILE ${path} sh ${path}/$(basename $SCRIPT_FILE) ${path} > /dev/null & fi done