Michael Loßin on Tue, 26 Feb 2002 19:32:07 +0100 (CET)(envelope-from owner-apsfilter-help@apsfilter.org)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: fake duplex page reordering? [patch]


[cc: to Rob]

On 25-Feb-02 Rob Mahurin wrote:
> I have just discovered apsfilter and its fake duplex option, which
> does the conversion cruft for me and has a much nicer restarting
> mechanism, which I like.  Unfortunately it doesn't reverse the odd
> pages, which means that I have to reorder all of the pages twice
> (once feeding them back in for the odd sides, and again before
> stapling them).  I am lazy and dislike this.  :)  How to fix it?

The problem is that there are a couple of paper feeding
mechanisms:
        - top loader (e.g. Epson Stylus)
          * first page printed will be on bottom
          * paper stack can be flipped as a whole
          * final stack will be in wrong order
        - front loader, DeskJet-style
          * first page printed will be on bottom
          * paper stack must be flipped one by one
          * final stack will be in wrong order
        - front loader, LaserJet-style
          * paper stack will be turned face down,
            but in correct order
          * paper stack must be flipped one by one
          * final stack will be in correct order

...and maybe some more.

So at least we need two distinct variables that control
reverse mode for odd *and* even pages.

> It seems that the way to change it would be 
> to add a DUPLEX_REVERSE option to the option set (in apsfilterrc?) and
> change print_ps_duplex() to print the extra blank page if
> the last page is odd and reverse the odd pages if DUPLEX_REVERSE is
> set. 
> 
> The first is a little tricky.  I don't really like my kludge for
> discovering the parity of the last page, but can't think of a prettier
> way to do so.  It looks like the code to add after the if statment
> inside the even-printing subshell would be
> 
>   [ "$DUPLEX_REVERSE" -a \
>       x$(( $(psselect -p_1 "$APS_TMPDIR/duplex.ps" 2>&1 > /dev/null\
>       | tr "[]" " \n" | head -1 ) % 2 ))x == x1x ] && \
>     echo . | print_ascii

The real problem seems to be to reliably insert a blank
page. Is it enough to do just "printf '\014´" or do we
need "psselect -p-,_" to insert the blank page at the
end?

> but that breaks your non-dependence on psselect and I'm not sure that

That doesn't hurt too much, the psutils are common enough.

> The second piece is straightforward to do: change the section
> where the odd pages are printed to something like
> 
>   local flag
>   if find_filter psselect; then
>      [ "$DUPLEX_REVERSE" ] && flag=-r
>      psselect -q -o $flag < "$APS_TMPDIR/duplex.ps"
>   else
>      # pstops exists, otherwise we wouldn't be here (see above)
>      [ "$DUPLEX_REVERSE" ] && flag=-
>      pstops -q 2:${flag}0 < "$APS_TMPDIR/duplex.ps"
>   fi | print_ps
> 
> I have just implemented these changes on my own system and they seem
> to work, so I'll dignify this message by calling it a "patch".  It's
> not complete because you need to tell the user when to use
> DUPLEX_REVERSE, but I don't think it's all that bad for a morning's
> effort.  

This might work on your printer, because you only need to
reverse the odd pages. I have tried the following:
[in print_ps_duplex()]

    if [ -p "$APS_TMPDIR/duplex-key" ]; then
        find_filter psselect || fatal_filter psselect

        # make page count even by adding a blank page if needed
        case $(ps_postprocessing | tee "$APS_TMPDIR/duplex.ps" | \
                psselect -p_1 2>&1 >/dev/null | tr "[]" " \n" | head -1) in
            *[13579])   is_odd=set ;;
            *)          unset is_odd ;;
        esac

        # don't process PostScript with the pstools again
        SKIP_POSTPROCESSING=set

        # print the even pages
        [ "$COPIES" != 1 ] && SAVE_DUPLEX_COPY=even
        psselect -q -e ${is_odd:+-p-,_} ${DUPLEX_REVERSE_EVEN:+-r} \
            < "$APS_TMPDIR/duplex.ps" | print_ps

        duplex_notification

        # print the odd pages
        [ "$COPIES" != 1 ] && SAVE_DUPLEX_COPY=odd
        psselect -q -o ${DUPLEX_REVERSE_ODD:+-r} < "$APS_TMPDIR/duplex.ps" | \
            print_ps
        rm -f "$APS_TMPDIR/duplex.ps"

        # turn on the copy machine!
[etc.]

While this correctly creates an even-paged document, the
blank page is skipped for no apparent reason. The "showpage"
command is in the PostScript code, but it's just ignored
by the printer driver -- oddly enough, the X11 driver does
show the blank page.


BUT :)  if I replace the "print even pages" part with

  # print the even pages
  [ "$COPIES" != 1 ] && SAVE_DUPLEX_COPY=even
  [ -n "$is_odd" -a -n "$DUPLEX_REVERSE_EVEN" ] && printf '\012\014'
  psselect -q -e ${DUPLEX_REVERSE_EVEN:+-r} | \
      < "$APS_TMPDIR/duplex.ps" | print_ps
  [ -n "$is_odd" -a -z "$DUPLEX_REVERSE_EVEN" ] && printf '\012\014'

it works as expected. (My printer needs one LF with one FF
to spit out a blank page.)

The big question is: Is this a portable way to create a
blank page? (I hope so...) However, it should not a big
problem to introduce a BLANK_PAGE='\012\014' variable,
let the user adjust it for his printer and then use
... && printf "$BLANK_PAGE"

> Thanks for writing such clear code, by the way.

Who, me?  ;^D


HTH
Michael