2

Public PAIR ( http://portal.uspto.gov/pair/PublicPair ) is a website provided by the USPTO that allows anybody to monitor and inspect the prosecution of US published patent applications.

Public PAIR not only displays information regarding application status but also - for applications filed after (about) 2000 - gives access to the prosecution history, i.e., all correspondence associated with a particular patent application. This information in Public PAIR is also referred to as the Image File Wrapper and accessible using a tab of the same name.

By way of example, the screenshot represents the Image File Wrapper of US patent application 11/161,345:

Image File Wrapper

The documents are sorted in chronological order, the most recent document on the top. You can click on the link provided in the column "Document Description" to view a single document. The system also permits to download a selection or all documents at once. To download all documents, 1. click the checkbox and 2. click the "PDF" button. Documents are provided in PDF format.

If you downloaded all documents at once, you'll end up with a single PDF file which includes bookmarks (or a table of contents, TOC) for each document. If your favorite PDF viewer supports bookmarks/TOC, you can quickly navigate through the PDF by clicking on the corresponding bookmark/TOC of the document you want to see.

If you have a large Image File Wrapper PDF containing the full prosecution history, how do you split it out into single PDF files?

I tried to follow the instructions provided here

https://answers.acrobatusers.com/how-split-multipage-pdf-file-q100034.aspx

but they are not helpful with regard to the Image File Wrapper PDF. The "split document" function aborts when the TOC entry can not be used as file name or if the file already exists.

1

As a self-appointed Unix guru ;-) 😉 and in accordance with StackExchange's roots, I ended up using command-line tools like "pdftk" and "perl" to solve this problem.

On an Apple Mac:

  1. install "pdftk" command-line tool (directly or via MacPorts)
  2. install perl
  3. copy this script into a text file and run it with a path to the Image File Wrapper PDF as argument.

#!/usr/bin/perl
# Splits a PDF file according to its bookmarks (aka. table of contents) into
# several smaller files. Uses "pdftk".
# V1.0
# Redistribution and use in source and binary forms, with or without modification, are permitted.
# This software is provided "as is" and any express or implied warranties, including, 
# but not limited to, the implied warranties of merchantability and fitness for a 
# particular purpose are disclaimed. In no event shall the copyright holder or 
# contributors be liable for any direct, indirect, incidental, special, exemplary, or
# consequential damages arising in any way out of the use of this software.

use strict;
use warnings;
$0 =~ s(^.*/)();

sub usage {
  print "usage: $0 [-n] <filewrapper.pdf>\n";
  print "  -n    dry run\n";
  exit(0);
}

sub get_bookmarks { # ($filename, \%bookmarks, \$number_of_pages)
  my $filename = shift;
  my $ref_bookmarks = shift;
  my $ref_max = shift;

  open(PIPE, "-|", "pdftk", $filename, "dump_data") || return 1;
  chomp(my @lines = <PIPE>);
  close(PIPE);
  return 2 if ($?);

  #NumberOfPages: 163
  #BookmarkBegin
  #BookmarkTitle: 2012-10-09 Non-Final Rejection
  #BookmarkLevel: 1
  #BookmarkPageNumber: 1
  #BookmarkBegin
  #BookmarkTitle: 2012-10-09 List of references cited by examiner
  #BookmarkLevel: 1
  #BookmarkPageNumber: 20

  %$ref_bookmarks = ();
  my $page = "";
  my $title = "";
  $$ref_max = 0;
  foreach my $line (@lines) {
    my @fields = split(/:\s+/, $line, 2);
    if ($fields[0] eq "BookmarkBegin") {
      $page = $title = "";
    } elsif ($fields[0] eq "BookmarkTitle") {
      $title = $fields[1];
    } elsif ($fields[0] eq "BookmarkPageNumber") {
      $page = $fields[1];
    } elsif ($fields[0] eq "NumberOfPages") {
      $$ref_max = $fields[1];
    }
    if ($page ne "" && $page > 0 && $title ne "") {
      $$ref_bookmarks{ $page } = $title;
      $page = $title = "";
    }
  }
}

my $dry_run = 0;
if ($ARGV[0] eq "-n") {
  $dry_run = 1;
  shift(@ARGV);
}

if (@ARGV != 1) {
  print "Error: check commandline!\n";
  usage();
}

my $filename = $ARGV[0];
if (! -r $filename) {
  die ("Error: Could not open '$filename'.\n");
}

my %bookmarks = ();
my $max = 0;

my $error = get_bookmarks($filename, \%bookmarks, \$max);
if ($error) {
  die("Error: Could not run 'pdftk'.\n") if ($error == 1);
  die("Error: pdftk reported an error. Aborting.\n");
}

print "Processing " . $max . " pages...\n";

my @pages_sorted = sort {$b <=> $a} keys %bookmarks; # reverse sort

if (@pages_sorted == 0) {
  print "No table of contents found.\n";
  exit(0);
}

my $begin = "";
my $end = "end";
$error = 0;
my @new_files = ();
for (my $i = 0; $i < @pages_sorted; $i++) {
  $begin = $pages_sorted[$i];
  my($date, $new_filename) = split (/\s+/, $bookmarks{ $begin }, 2);
  # sanitize filename
  # add characters which your filesystem dislikes into [ ] brackets
  $new_filename =~ s([/;\\])(_)g;
  $new_filename =  $date . " " . sprintf("%03d", $i + 1) . " " . $new_filename . ".pdf";
  push(@new_files, $new_filename);
  my @cmd = ( "pdftk", $filename, "cat", $begin . "-" . $end, "output", $new_filename );
  $end = $begin - 1;
  if ($dry_run) {
    print join(" ", @cmd) . "\n";
  } else {
    print $bookmarks{ $begin } . "\n";
    system @cmd;
    if ($?) {
      $error++;
    } else {
    }
  }
}

if ($error) {
  die("Errors occurred during processing of $error file(s).\n");
} elsif (! $dry_run) {
  print "Checking for completeness...";
  my $page_count = 0;
  foreach my $pdf (@new_files) {
    my $c = 0;
    get_bookmarks($pdf, {} , \$c );
    $page_count += $c;
  }
  if ($page_count == $max) {
    print "No errors.\nCreated " . @pages_sorted . " PDF files containing a total of $page_count pages.\n";
  } else {
    print "\n";
    print "Error: All documents have been extracted but the total number of pages\n";
    print "       in all extracted documents is $page_count and does not match the number\n";
    print "       of $max pages in the source document '$filename'.\n";
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.