File: pdfmerge.ml

package info (click to toggle)
camlpdf 0.5-1
  • links: PTS, VCS
  • area: non-free
  • in suites: squeeze, wheezy
  • size: 1,516 kB
  • ctags: 2,689
  • sloc: ml: 18,229; ansic: 139; makefile: 139
file content (38 lines) | stat: -rw-r--r-- 1,580 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
(* \chaptertitle{Pdfmerge}{Concatentate documents} *)

(* Summary: \texttt{pdfmerge a.pdf b.pdf c.pdf} appends \texttt{b.pdf} to
\texttt{a.pdf} and writes to \texttt{c.pdf}. *)
open Utility

(* We read all the files, read their pages and concatenate them, dealing with
clashing object numbers. We then build a new page tree, and build the output PDF
document, with a new root and trailer dictionary. We then remove any unreferenced
objects, and write to file. *)
let merge_pdfs pdfs out_name =
  let pdfs = Pdf.renumber_pdfs pdfs
  and minor' = fold_left max 0 (map (fun p -> p.Pdf.minor) pdfs) in
    let pages = flatten (map Pdfdoc.pages_of_pagetree pdfs)
    and pdf = ref (Pdf.empty ()) in
      iter (Pdf.objiter (fun k v -> ignore (Pdf.addobj_given_num !pdf (k, v)))) pdfs;
      let pdf, pagetree_num = Pdfdoc.add_pagetree pages !pdf in
        let pdf = Pdfdoc.add_root pagetree_num [] pdf in
          let pdf = {pdf with Pdf.major = 1; Pdf.minor = minor'} in
            Pdf.remove_unreferenced pdf;
            pdf

(* Read command line arguments, read files, call [merge], write result. *)
let _ =
  let in_names, out_name =
    match rev (tl (Array.to_list Sys.argv)) with
    | h::t::t' -> rev (t::t'), h
    | _ -> print_string "Syntax: pdfmerge <inputs> <output>\n\n"; exit 1
  in
    try
      let pdfs = map (Pdfread.pdf_of_file None) in_names in
        let result = merge_pdfs pdfs out_name in
          Pdfwrite.pdf_to_file result out_name
    with
      err ->
        Printf.printf "Failed to merge files.\n%s\n\n" (Printexc.to_string err);
        exit 1