DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 20th December 2017
shep shep is offline
Real Name: Scott
Arp Constable
 
Join Date: May 2008
Location: Dry and Dusty
Posts: 1,503
Default PDF/Postscript -> print filter -> Print Queue Filter

The cups-filters pkg README has instructions to use a foomatic-rip with a ppd. The instructions advise the use of a2ps, or enscript, I believe that a2ps detects postscript files and passes them on to the printer while txt files are converted to *.ps on their way to the printer. One thing I have noticed is that /etc/a2ps.cfg has entries to also generate postscript out of a pdf. For me, printing a pdf from the command line does not work with a2ps.

The FreeBSD handbook has a "Smart Filters" example that will call enscript if a postscript file is not detected: the first 4 characters of a postscript file are
Quote:
%!PS"
The first 4 characters of a pdf file are
Quote:
%PDF
so I thought the Smart Filter could be expanded to detect a pdf and filter it through pdftops print/poppler. I modified the script provided by W. Block to detect pdf files and hopefully convert to postscript.

The last piece of this is that I predominately use 2 print queues: lp: simplex letter and duplex: duplex letter. Both queues work when I use evince/xpdf/gv/pdftops but I get an "undefined command h operand stack" printed out with the following:
/usr/local/libexec/print_filter
Code:
#!/bin/sh
#
#  print_filter - Print PostScript, PDF or plain text on a PostScript printer
#
IFS="" read -r first_line
first_four_chars=`expr "$first_line" : '\(....\)'`

case "$first_four_chars" in
%!PS)
    echo "$first_line" && cat && exit 0
    exit 2
    ;;
%PDF)
    ( echo "$first_line"; cat ) | /usr/local/bin/pdftops - | && exit 0
    exit 2
    ;;
*)
    ( echo "$first_line"; cat ) | /usr/local/bin/enscript -o - && exit 0
    exit 2
    ;;
esac
/usr/local/libexec/br_script_duplex
Code:
#!/bin/sh

/usr/local/libexec/print_filter | \
 /usr/local/bin/foomatic-rip --ppd \
 /etc/foomatic/direct/Brother-HL-5450DN_BR-Script3-Postscript-Brother-en.ppd \
 -o PageSize=Letter -o Duplex=DuplexNoTumble
My older pcl5e printer would detect *ps, *pdf and *txt with a ghostscript filter. What is the best way to pipe the output from print_filter -> queue filter? Is it acceptable to use scripts sequentially? I could create pdf/pdf-duplex and txt print queues but it seems less elegant.

Last edited by shep; 21st December 2017 at 12:08 AM.
Reply With Quote
  #2   (View Single Post)  
Old 14th December 2018
fvgit's Avatar
fvgit fvgit is offline
Spikes in tights
 
Join Date: May 2016
Location: perl -MMIME::Base64 -le 'print decode_base64("U2hlcndvb2QgRm9yZXN0")'
Posts: 314
Default

I know this was posted a year ago, but I'm stuck with what seems to be a similar problem. Apparently pdftops doesn't like pipes.

Were you successful printing PDF files with the smart filter?
Reply With Quote
  #3   (View Single Post)  
Old 14th December 2018
shep shep is offline
Real Name: Scott
Arp Constable
 
Join Date: May 2008
Location: Dry and Dusty
Posts: 1,503
Default

I gave up on it. It is not something I do frequently so I just do it in 2 steps or use print/gv or the light version of graphics/evince. IIRC, there were issues with documents formated as PDF1.7.
Reply With Quote
  #4   (View Single Post)  
Old 14th December 2018
fvgit's Avatar
fvgit fvgit is offline
Spikes in tights
 
Join Date: May 2016
Location: perl -MMIME::Base64 -le 'print decode_base64("U2hlcndvb2QgRm9yZXN0")'
Posts: 314
Default

Quite understandable given how picky these conversion tools seem to be. I'm currently sidestepping the issue with aliased mini scripts like this for local printing:

Code:
#!/bin/sh
pdftops $1 - | lpr -Pmyprintername
or like the following for secure network printing (works best with key-based authentication):
Code:
#!/bin/sh
pdftops $1 - | ssh user@remotehost 'lpr'
I'm not willing to give up on the smart filter, though. It seems I'll have to keep calm and carry on digging.
Reply With Quote
  #5   (View Single Post)  
Old 18th December 2018
fvgit's Avatar
fvgit fvgit is offline
Spikes in tights
 
Join Date: May 2016
Location: perl -MMIME::Base64 -le 'print decode_base64("U2hlcndvb2QgRm9yZXN0")'
Posts: 314
Default

Ok, I solved the problem using a temporary file (mktemp(2)). Not necessarily an elegant solution but it works. By modifying your smart filter in the following way (adding the orange parts and removing the pipe '|' after pdftops) it should be able to print pdfs:

Code:
#!/bin/sh
#
#  print_filter - Print PostScript, PDF or plain text on a PostScript printer
#
IFS="" read -r first_line
first_four_chars=`expr "$first_line" : '\(....\)'`

case "$first_four_chars" in
%!PS)
    echo "$first_line" && cat && exit 0
    exit 2
    ;;
%PDF)
   TMPFILE=$(mktemp /tmp/printtmp.XXXXXXXXXX) || exit 1
    ( echo "$first_line"; cat ) > $TMPFILE | /usr/local/bin/pdftops $TMPFILE - && exit 0
    rm $TMPFILE
    exit 2
    ;;
*)
    ( echo "$first_line"; cat ) | /usr/local/bin/enscript -o - && exit 0
    exit 2
    ;;
esac
I can't do real testing as my own printer needs PCL-input. But a quick command line test always produces PostScript output whether I pipe a PDF or a genuine PS file as input. You should be able to further pipe it without difficulty.

For my own printer I have to add a second conversion from postscript to pcl (script is based on an example from the FreeBSD docs):
Code:
#!/bin/sh

#
#  Treat LF as CR+LF to avoid the staircase effect:
#
#  (this sends a PCL command to the printer, see:                              
#  http://h10032.www1.hp.com/ctg/Manual/bpl13205.pdf p. 12, "Line Termination")
#
printf "\033&k2G" || exit 2

#
#  Read first four characters of the file                                      
#
read first_line
first_four_chars=`expr "$first_line" : '\(....\)'`                             

if [ "$first_four_chars" = "%!PS" ]; then                                      
    #
    #  It is PostScript; use Ghostscript to scan-convert and print it.         
    #
    #  Note that PostScript files are actually interpreted programs,           
    #  and those programs are allowed to write to stdout, which will           
    #  mess up the printed output.  So, we redirect stdout to stderr           
    #  and then make descriptor 3 go to stdout, and have Ghostscript           
    #  write its output there.  Exercise for the clever reader:                
    #  capture the stderr output from Ghostscript and mail it back to          
    #  the user originating the print job.                                     
    #
    exec 3>&1 1>&2
    /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=ljet4 \                    
        -sOutputFile=/dev/fd/3 - && exit 0                                     

    /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=ljet4 -sOutputFile=- - \   
        && exit 0

elif [ "$first_four_chars" = "%PDF" ]; then                                    
    #
    #  Convert PDF-files with Poppler & Ghostscript:                            
    #
    #  create a temporary file for pdftops to read from,                       
    #  redirect input into it,
    #  do the pdftops conversion from tempfile to stdout,                      
    #  and pipe the result to gs for conversion to PCL-output (ljet4)          
    #
    TMPFILE=$(mktemp /tmp/printtmp.XXXXXXXXXX) || exit 1                       
    ( echo "$first_line"; cat ) > $TMPFILE \                                   
        && /usr/local/bin/pdftops $TMPFILE - \                                 
        | /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=ljet4 \              
           -sOutputFile=- - \
        && rm $TMPFILE && exit 0
else
    #
    #  Plain text or HP/PCL, so just print it directly; print a form feed      
    #  at the end to eject the last page.                                      
    #
    echo $first_line && cat && printf "\033&l0H" &&                            
exit 0
fi

exit 2
With this in place I can now throw PostScript, ASCII, and PDF files in my printer's general direction and have it print properly just by typing lpr filename.

The temp file approach also works with Ghostscript's pdf2ps, but I'd recommend against using it. Converting a 60M pdf file with pdf2ps yielded a 1.3G postscript file. I shudder to think what monstrosity of a file it would create out of a >500M pdf I have on my hard drive.
Reply With Quote
  #6   (View Single Post)  
Old 24th December 2018
fvgit's Avatar
fvgit fvgit is offline
Spikes in tights
 
Join Date: May 2016
Location: perl -MMIME::Base64 -le 'print decode_base64("U2hlcndvb2QgRm9yZXN0")'
Posts: 314
Default

Just in time for Christmas I figured out how do the pdf/ps conversion without the need for a temporary file.

This is shep's original script with just one additional character in a nice christmassy red:
Code:
#!/bin/sh
#
#  print_filter - Print PostScript, PDF or plain text on a PostScript printer
#
IFS="" read -r first_line
first_four_chars=`expr "$first_line" : '\(....\)'`

case "$first_four_chars" in
%!PS)
    echo "$first_line" && cat && exit 0
    exit 2
    ;;
%PDF)
    ( echo "$first_line"; cat ) | /usr/local/bin/pdftops - - && exit 0
    exit 2
    ;;
*)
    ( echo "$first_line"; cat ) | /usr/local/bin/enscript -o - && exit 0
    exit 2
    ;;
esac
Both pdf2ps and pdftops expect the program infile outfile syntax. The trick is to use '-' twice, one for the infile and one for the outfile. Shep's original script was just missing a hyphen.

That concludes my third post in a row, but all good things come in threes. Enjoy.
Reply With Quote
  #7   (View Single Post)  
Old 24th December 2018
shep shep is offline
Real Name: Scott
Arp Constable
 
Join Date: May 2008
Location: Dry and Dusty
Posts: 1,503
Default

For lack of a hyphen

Thanks.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
ultp? libusb? cups - Can't print npmaier FreeBSD General 2 13th October 2012 04:12 AM
echo and print ? sharris FreeBSD General 1 4th September 2011 06:25 AM
Windows scripts can't print drhowarddrfine Other OS 15 31st March 2009 08:53 AM
Can't Print (Fresh First Time install) BSD newb Xero FreeBSD Installation and Upgrading 4 15th February 2009 07:11 PM
Print on remote WinXP from web host drhowarddrfine General software and network 5 13th October 2008 05:41 PM


All times are GMT. The time now is 06:30 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick