001/*
002 *  DeletePDFPages
003 *  A tool to manipulate PDF files by cropping each page by the specified
004 *  amounts.
005 *
006 *  $URL: svn://svn.webarts.bc.ca/open/trunk/projects/WebARTS/ca/bc/webarts/tools/pdf/DeletePDFPages.java $
007 *  Copyright (C) 2003 Tom Gutwin
008 *  tgutwin@webarts.bc.ca
009 *
010 *
011 *  This program is free software; you can redistribute it and/or
012 *  modify it under the terms of the GNU General Public License
013 *  as published by the Free Software Foundation; either version 2
014 *  of the License, or any later version.
015 *
016 *  This program is distributed in the hope that it will be useful,
017 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
018 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
019 *  GNU General Public License for more details.
020 *
021 *  You should have received a copy of the GNU General Public License
022 *  along with the jEdit program; if not, write to the Free Software
023 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
024 */
025
026package ca.bc.webarts.tools.pdf;
027
028import java.io.File;
029import java.io.FileOutputStream;
030
031import com.itextpdf.text.Document;
032import com.itextpdf.text.PageSize;
033import com.itextpdf.text.pdf.PdfContentByte;
034import com.itextpdf.text.pdf.PdfImportedPage;
035import com.itextpdf.text.pdf.PdfReader;
036import com.itextpdf.text.pdf.PdfWriter;
037import com.itextpdf.text.Rectangle;
038
039
040/**
041 *  A tool to manipulate PDF files by deleting each page specified by the input.
042 *
043 *  <br>
044 *  This class can be called from the commandline or instantiated and used from
045 *  other Java Objects.<br><br>
046 *  <b><u>Commandline Syntax:</u></b><br>
047 *  java ca.bc.webarts.tools.pdfDeletePDFPages PDFFilename page1ToDelete
048 *  page2ToDelete page3ToDelete ...<br />
049 *  where you can have as many integers on the commandline as pages you want
050 *  to delete.<br>
051 *
052 * @author    tgutwin
053 */
054public class DeletePDFPages
055{
056  /** Default input filename. **/
057  public static final String DEFAULT_INPUT_FILENAME = "infile.pdf";
058
059  /**  The input filename that will be cropped and saved in output filename.
060   *   DEFAULT = infile.pdf**/
061  private static String inFileName_ = DEFAULT_INPUT_FILENAME;
062
063  /**  The output filename string. DEFAULT = infile-Deleted.pdf**/
064  private static String outFileName_ = "infile-Deleted.pdf";
065
066
067  /**  The size of the resultant page. */
068  private static Rectangle outputPageSize_ = PageSize.LETTER;//PageSize.A4;
069
070  /**  Flags the auto execution of acro reader after the cropping.
071   *   DEFAULT = false **/
072  private static boolean launchAcroread_ = false;
073
074  /**  Flags whether the gui launches on startup.
075   *   DEFAULT = false **/
076  private static boolean launchGui_ = false;
077
078  /**  The path/command to run the acroreader. **/
079  private static String acroCmd_ = "/home/tgutwin/bin/acro";
080
081  /**  The usage string. **/
082  private static String usage_ = "SYNTAX: DeletePDFPages PDFFilename [pageNumToDelete ...]";
083
084  private int [] deletePages_ = null;
085
086
087  /**
088   * Default Constructor assumes default values for EVERYTHING.
089   **/
090   public DeletePDFPages()
091   {
092
093   }
094
095
096  /**
097   * Constructor that takes the edge crop sizes in inches.
098   **/
099   public DeletePDFPages(int [] deletePages)
100   {
101     setDeletePages(deletePages);
102   }
103
104
105  /**
106   *  The main program for the DeletePDFPages class
107   *
108   * @param  args  The command line arguments
109   */
110  public static void main(String[] args)
111  {
112    DeletePDFPages instance = new DeletePDFPages();
113    boolean validParms = instance.parseCmdlineParms(args);
114
115
116    /*
117     *  Parms are now parsed.... start the transform/crop
118     */
119    if (validParms)
120    {
121      if (launchGui_)
122      {
123        // launch gui for crop info
124      }
125      else
126        // just do the crop
127        instance.doDelete();
128    }
129    else
130    {
131      // nothing for now.
132    }
133  }
134
135
136  /**
137   * Parses the input commandline parameters and assigns the various class
138   * variables.
139   *
140   * @return success or failure
141   **/
142  public boolean parseCmdlineParms(String [] args)
143  {
144    boolean retVal = false;
145
146    if (args.length > 1)
147    {
148      setInFileName(args[0]);
149      setOutFileName(null);
150      deletePages_ = new int[args.length -1];
151      for (int i = 0; i < args.length -1; i++)
152        deletePages_[i] = Integer.parseInt(args[i+1]) -1;
153      retVal = true;
154    }
155    else
156      System.out.println(usage_);
157
158    return retVal;
159  }
160
161
162
163  /**
164   * Executes the deleting as specified by the class parms.
165   *
166   * @return success or failure
167   **/
168  public boolean doDelete()
169  {
170    boolean retVal = true;
171
172    try
173    {
174      // we create a reader for a certain document
175      System.out.println("Reading: " + inFileName_);
176      PdfReader reader = new PdfReader(inFileName_);
177
178      // step 1: creation of a document-object
179      // we retrieve the total number of pages
180      int numPages = reader.getNumberOfPages();
181      Document document =
182          new Document(outputPageSize_, 0, 0, 0, 0);// Margins: left, right,top, bottom
183
184      // step 2: we create a writer that listens to the document
185      System.out.println("Writing: " + outFileName_);
186      FileOutputStream outFileStream = new FileOutputStream(outFileName_);
187      PdfWriter writer = PdfWriter.getInstance(document, outFileStream);
188
189      // step 3: we open the document
190      document.open();
191
192      // step 4: calculate the new scaling / layout postion
193      PdfContentByte cb = writer.getDirectContent();
194      System.out.println("There are " + numPages +
195          " pages in the document.");
196       System.out.println("Deleting " + deletePages_.length +
197          " pages.");
198      PdfImportedPage leftPage;
199      int currentPage = 0;
200
201
202      /*
203       *  step 5: Start Copying the pages to the new Doc (in 2Up format)
204       */
205      /*
206       *  ******* ******************************************************
207       */
208      System.out.print(" Adding pages: ");
209      while (currentPage < numPages)
210      {
211        if (!pageToDelete(currentPage))
212        {
213          System.out.print((currentPage+1)+" " );
214          document.newPage();
215          leftPage = writer.getImportedPage(reader, ++currentPage);
216          cb.addTemplate(leftPage,0.0f,0.0f); //, a, b, c, d, -(leftCropBorder_* 72.0f),
217                                    //           -(bottomCropBorder_* 72.0f));
218        }
219        else
220          currentPage++;
221      }
222      System.out.println(" ." );
223
224      // step 6: we close the document
225      document.close();
226    }
227    catch (Exception de)
228    {
229      de.printStackTrace();
230      retVal = false;
231    }
232
233    return retVal;
234  }
235
236
237  private boolean pageToDelete(int num)
238  {
239    boolean retVal = false;
240    for (int i=0; !retVal && i < deletePages_.length;i++)
241      if (deletePages_[i] == num)
242        retVal = true;
243    return retVal;
244  }
245
246
247  /**
248   * Setter.
249   **/
250  public void setDeletePages(int [] parm)
251  {
252    this.deletePages_ = parm;
253  }
254
255
256  /**
257   * Getter.
258   **/
259  public int [] getDeletePages()
260  {
261    return deletePages_;
262  }
263
264
265  /**
266   * Setter for input filename. IT MUST END WITH A ".pdf".
267   **/
268  public void setInFileName(String inFileName)
269  {
270    if (inFileName == null ||
271        inFileName.equals("") ||
272        !inFileName.endsWith(".pdf"))
273      this.inFileName_ = DEFAULT_INPUT_FILENAME;
274    else
275      this.inFileName_ = inFileName;
276  }
277
278
279  /**
280   * Getter.
281   **/
282  public String getInFileName()
283  {
284    return inFileName_;
285  }
286
287
288  /**
289   * Setter.
290   **/
291  public void setOutFileName()
292  {
293    setOutFileName(null);
294  }
295
296
297  /**
298   * Setter.
299   **/
300  public void setOutFileName(String outFileName)
301  {
302    if (outFileName == null || outFileName.equals(""))
303      this.outFileName_ = this.inFileName_.substring(
304                              0, this.inFileName_.length() - 4) + "-Deleted.pdf";
305    else
306      this.outFileName_ = outFileName;
307  }
308
309
310  /**
311   * Getter.
312   **/
313  public String getOutFileName()
314  {
315    return outFileName_;
316  }
317
318
319}
320