diff --git a/cpdf.ml b/cpdf.ml index 112d80d..615dc8b 100644 --- a/cpdf.ml +++ b/cpdf.ml @@ -833,8 +833,30 @@ let output_string_of_target pdf fastrefnums x = "\"" ^ Pdfwrite.string_of_pdf a ^ "\"" | x -> "\"" ^ Pdfwrite.string_of_pdf x ^ "\"" +let json_of_target pdf fastrefnums x = + match Pdfdest.pdfobject_of_destination x with + | Pdf.Array (_::more) -> + let a = + Pdf.Array (Pdf.Integer (Pdfpage.pagenumber_of_target ~fastrefnums pdf x)::more) + in + Cpdfjson.json_of_object pdf (fun _ -> ()) false false a + | x -> Cpdfjson.json_of_object pdf (fun _ -> ()) false false x + +let output_json_marks ch calculate_page_number pdf fastrefnums marks = + let module J = Cpdfyojson.Safe in + let json_of_mark m = + `Assoc + [("level", `Int m.Pdfmarks.level); + ("text", `String m.Pdfmarks.text); + ("page", `Int (calculate_page_number m)); + ("open", `Bool m.Pdfmarks.isopen); + ("target", json_of_target pdf fastrefnums m.Pdfmarks.target)] + in + let json = `List (map json_of_mark marks) in + J.pretty_to_channel ch json + (* List the bookmarks, optionally deunicoding the text, in the given range to the given output *) -let list_bookmarks encoding range pdf output = +let list_bookmarks ~json encoding range pdf output = let process_stripped escaped = let b = Buffer.create 200 in iter @@ -889,16 +911,19 @@ let list_bookmarks encoding range pdf output = * we add one. Pdfpage.pagenumber_of_target has been modified to support this.*) Pdfpage.pagenumber_of_target ~fastrefnums pdf mark.Pdfmarks.target in - iter - (function mark -> - output.Pdfio.output_string - (Printf.sprintf "%i \"%s\" %i%s %s\n" - mark.Pdfmarks.level - (process_string mark.Pdfmarks.text) - (calculate_page_number mark) - (if mark.Pdfmarks.isopen then " open" else "") - (output_string_of_target pdf fastrefnums mark.Pdfmarks.target))) - inrange + if json then + output_json_marks stdout calculate_page_number pdf fastrefnums inrange + else + iter + (function mark -> + output.Pdfio.output_string + (Printf.sprintf "%i \"%s\" %i%s %s\n" + mark.Pdfmarks.level + (process_string mark.Pdfmarks.text) + (calculate_page_number mark) + (if mark.Pdfmarks.isopen then " open" else "") + (output_string_of_target pdf fastrefnums mark.Pdfmarks.target))) + inrange (* o is the stamp, u is the main pdf page *) diff --git a/cpdf.mli b/cpdf.mli index 25a6473..09aabcc 100644 --- a/cpdf.mli +++ b/cpdf.mli @@ -101,7 +101,7 @@ val add_bookmarks : bool -> Pdfio.input -> Pdf.t -> Pdf.t (** [list_bookmarks encoding range pdf output] lists the bookmarks to the given output in the format specified in cpdfmanual.pdf *) -val list_bookmarks : encoding -> int list -> Pdf.t -> Pdfio.output -> unit +val list_bookmarks : json:bool -> encoding -> int list -> Pdf.t -> Pdfio.output -> unit (** {2 XML Metadata} *) diff --git a/cpdfcommand.ml b/cpdfcommand.ml index e5ce25d..e7a2ded 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -678,7 +678,7 @@ let reset_arguments () = args.impose_margin <- 0.; args.impose_spacing <- 0.; args.impose_linewidth <- 0.; - args.bookmarks_json <- true + args.bookmarks_json <- false (* Do not reset original_filename or cpdflin or was_encrypted or * was_decrypted_with_owner or recrypt or producer or creator or path_to_* or * gs_malformed or gs_quiet, since we want these to work across ANDs. Or @@ -3448,7 +3448,7 @@ let go () = | (_, pagespec, _, _, _, _)::_, _ -> let pdf = get_single_pdf args.op true in let range = parse_pagespec_allow_empty pdf pagespec in - Cpdf.list_bookmarks args.encoding range pdf (Pdfio.output_of_channel stdout); + Cpdf.list_bookmarks args.bookmarks_json args.encoding range pdf (Pdfio.output_of_channel stdout); flush stdout | _ -> error "list-bookmarks: bad command line" end diff --git a/cpdfjson.mli b/cpdfjson.mli index 6abe8cb..51e309c 100644 --- a/cpdfjson.mli +++ b/cpdfjson.mli @@ -1,2 +1,3 @@ +val json_of_object : Pdf.t -> (int -> unit) -> bool -> bool -> Pdf.pdfobject -> Cpdfyojson.Safe.t val to_output : Pdfio.output -> parse_content:bool -> no_stream_data:bool -> decompress_streams:bool -> Pdf.t -> unit val of_input : Pdfio.input -> Pdf.t