json add bookmarks done

This commit is contained in:
John Whitington 2021-10-27 13:16:55 +01:00
parent e3abffb21c
commit 169dff86b4
3 changed files with 63 additions and 38 deletions

52
cpdf.ml
View File

@ -599,15 +599,9 @@ let debug_bookmark_string s =
(* If optionaldest = [Pdfgenlex.LexString s], we parse the string, convert the (* If optionaldest = [Pdfgenlex.LexString s], we parse the string, convert the
* integer to an indirect of the real page target, and then put it in. *) * integer to an indirect of the real page target, and then put it in. *)
let bookmark_of_data pdf i s i' isopen optionaldest = let target_of_markfile_obj pdf i' pdfobj =
let target =
match optionaldest with
| [Pdfgenlex.LexString s] ->
let pdfobj =
Pdfread.parse_single_object s
in
(*Printf.printf "Parsed %s\n" (Pdfwrite.string_of_pdf pdfobj);*) (*Printf.printf "Parsed %s\n" (Pdfwrite.string_of_pdf pdfobj);*)
begin match pdfobj with match pdfobj with
Pdf.Array (Pdf.Integer x::more) -> Pdf.Array (Pdf.Integer x::more) ->
let pageobjnum = Pdfpage.page_object_number pdf i' in let pageobjnum = Pdfpage.page_object_number pdf i' in
begin match pageobjnum with begin match pageobjnum with
@ -620,22 +614,52 @@ let bookmark_of_data pdf i s i' isopen optionaldest =
| Pdf.Null -> Pdfdest.NullDestination | Pdf.Null -> Pdfdest.NullDestination
| Pdf.String s -> Pdfdest.read_destination pdf (Pdf.String s) | Pdf.String s -> Pdfdest.read_destination pdf (Pdf.String s)
| x -> Pdfdest.Action x | x -> Pdfdest.Action x
end
let target_of_markfile_target pdf i' = function
| [Pdfgenlex.LexString s] ->
let pdfobj = Pdfread.parse_single_object s in
target_of_markfile_obj pdf i' pdfobj
| _ -> Pdfpage.target_of_pagenumber pdf i' | _ -> Pdfpage.target_of_pagenumber pdf i'
in
let bookmark_of_data pdf i s i' isopen optionaldest =
(*debug_bookmark_string s; (*debug_bookmark_string s;
debug_bookmark_string (implode (fixup_characters [] (explode s))); debug_bookmark_string (implode (fixup_characters [] (explode s)));
debug_bookmark_string (Pdftext.pdfdocstring_of_utf8 (implode (fixup_characters [] (explode s))));*) debug_bookmark_string (Pdftext.pdfdocstring_of_utf8 (implode (fixup_characters [] (explode s))));*)
{Pdfmarks.level = i; {Pdfmarks.level = i;
Pdfmarks.text = Pdftext.pdfdocstring_of_utf8 (implode (fixup_characters [] (explode s))); Pdfmarks.text = Pdftext.pdfdocstring_of_utf8 (implode (fixup_characters [] (explode s)));
Pdfmarks.target = target; Pdfmarks.target = target_of_markfile_target pdf i' optionaldest;
Pdfmarks.isopen = isopen} Pdfmarks.isopen = isopen}
let parse_bookmark_file_json verify pdf input = let target_of_json_target pdf pagenumber target =
target_of_markfile_obj pdf pagenumber (Cpdfjson.object_of_json target)
let mark_of_json pdf = function
| `Assoc [("level", `Int level);
("text", `String text);
("page", `Int pagenumber);
("open", `Bool openstatus);
("target", target)] ->
{Pdfmarks.level = level;
Pdfmarks.text = text;
Pdfmarks.target = target_of_json_target pdf pagenumber target;
Pdfmarks.isopen = openstatus}
| _ -> error "malformed mark in mark_of_json"
let marks_of_json pdf = function
| `List ms -> map (mark_of_json pdf) ms
| _ -> error "top level of JSON boomark file not a list"
let parse_bookmark_file_json verify pdf i =
let module J = Cpdfyojson.Safe in
try try
let marks = let json =
[] match i.Pdfio.caml_channel with
| Some ch -> J.from_channel ch
| None ->
let content = Pdfio.string_of_bytes (Pdfio.bytes_of_input i 0 i.Pdfio.in_channel_length) in
J.from_string content
in in
let marks = marks_of_json pdf json in
if verify then if verify then
if verify_bookmarks pdf 0 (Pdfpage.endpage pdf) marks then marks else if verify_bookmarks pdf 0 (Pdfpage.endpage pdf) marks then marks else
error "Bad bookmark file (References non-existant pages or is malformed)" error "Bad bookmark file (References non-existant pages or is malformed)"

View File

@ -1,3 +1,4 @@
val json_of_object : Pdf.t -> (int -> unit) -> bool -> bool -> Pdf.pdfobject -> Cpdfyojson.Safe.t val json_of_object : Pdf.t -> (int -> unit) -> bool -> bool -> Pdf.pdfobject -> Cpdfyojson.Safe.t
val object_of_json : Cpdfyojson.Safe.t -> Pdf.pdfobject
val to_output : Pdfio.output -> parse_content:bool -> no_stream_data:bool -> decompress_streams:bool -> Pdf.t -> unit 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 val of_input : Pdfio.input -> Pdf.t

View File

@ -2,7 +2,7 @@
%Document -decrypt-force %Document -decrypt-force
%Document -collate %Document -collate
%Document -impose and friends (inc. 0-w, 0-h for long ones, how lines scale etc., undefined if pages different sizes) %Document -impose and friends (inc. 0-w, 0-h for long ones, how lines scale etc., undefined if pages different sizes)
%Document -bookmarks-json %Document -bookmarks-json including special "none" target
\documentclass{book} \documentclass{book}
% Edit here to produce cpdfmanual.pdf, cpdflibmanual.pdf, pycpdfmanual.pdf etc. % Edit here to produce cpdfmanual.pdf, cpdflibmanual.pdf, pycpdfmanual.pdf etc.