PDF Printing

From SlackWiki
Revision as of 16:14, 17 February 2010 by Allend (talk | contribs) (Created page with 'Category:Tips == 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 ...')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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