toc-bookmark

This commit is contained in:
John Whitington 2021-12-10 12:58:30 +00:00
parent 21bf568d87
commit 3bc02d71ec
3 changed files with 28 additions and 8 deletions

View File

@ -476,7 +476,8 @@ type args =
mutable format_json : bool; mutable format_json : bool;
mutable replace_dict_entry_value : Pdf.pdfobject; mutable replace_dict_entry_value : Pdf.pdfobject;
mutable dict_entry_search : Pdf.pdfobject option; mutable dict_entry_search : Pdf.pdfobject option;
mutable toc_title : string} mutable toc_title : string;
mutable toc_bookmark : bool}
let args = let args =
{op = None; {op = None;
@ -593,7 +594,8 @@ let args =
format_json = false; format_json = false;
replace_dict_entry_value = Pdf.Null; replace_dict_entry_value = Pdf.Null;
dict_entry_search = None; dict_entry_search = None;
toc_title = "Table of Contents"} toc_title = "Table of Contents";
toc_bookmark = true}
let reset_arguments () = let reset_arguments () =
args.op <- None; args.op <- None;
@ -695,7 +697,8 @@ let reset_arguments () =
args.format_json <- false; args.format_json <- false;
args.replace_dict_entry_value <- Pdf.Null; args.replace_dict_entry_value <- Pdf.Null;
args.dict_entry_search <- None; args.dict_entry_search <- None;
args.toc_title <- "Table of Contents" args.toc_title <- "Table of Contents";
args.toc_bookmark <- true
(* Do not reset original_filename or cpdflin or was_encrypted or (* 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 * 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 * gs_malformed or gs_quiet, since we want these to work across ANDs. Or
@ -1638,6 +1641,9 @@ let settypeset s =
let settableofcontentstitle s = let settableofcontentstitle s =
args.toc_title <- s args.toc_title <- s
let settocnobookmark () =
args.toc_bookmark <- false
let whingemalformed () = let whingemalformed () =
prerr_string "Command line must be of exactly the form\ncpdf <infile> -gs <path> -gs-malformed-force -o <outfile>\n"; prerr_string "Command line must be of exactly the form\ncpdf <infile> -gs <path> -gs-malformed-force -o <outfile>\n";
exit 1 exit 1
@ -2395,9 +2401,12 @@ and specs =
("-table-of-contents", ("-table-of-contents",
Arg.Unit (setop TableOfContents), Arg.Unit (setop TableOfContents),
" Typeset a table of contents from bookmarks"); " Typeset a table of contents from bookmarks");
("-table-of-contents-title", ("-toc-title",
Arg.String settableofcontentstitle, Arg.String settableofcontentstitle,
" Set (or clear if empty) the TOC title"); " Set (or clear if empty) the TOC title");
("-toc-no-bookmark",
Arg.Unit settocnobookmark,
" Don't add the table of contents to the bookmarks");
("-typeset", ("-typeset",
Arg.String settypeset, Arg.String settypeset,
" Typeset a text file as a PDF"); " Typeset a text file as a PDF");
@ -3843,7 +3852,7 @@ let go () =
let font = let font =
match args.font with StandardFont f -> f | _ -> error "TOC requires standard font only" match args.font with StandardFont f -> f | _ -> error "TOC requires standard font only"
in in
let pdf = Cpdftoc.typeset_table_of_contents ~font ~fontsize:args.fontsize ~title:args.toc_title pdf in let pdf = Cpdftoc.typeset_table_of_contents ~font ~fontsize:args.fontsize ~title:args.toc_title ~bookmark:args.toc_bookmark pdf in
write_pdf false pdf write_pdf false pdf
| Some (Typeset filename) -> | Some (Typeset filename) ->
let text = Pdfio.bytes_of_input_channel (open_in filename) in let text = Pdfio.bytes_of_input_channel (open_in filename) in

View File

@ -22,7 +22,7 @@ let of_pdfdocencoding f t =
(and CropBox) copied from first page of existing PDF. Margin of 50pts inside (and CropBox) copied from first page of existing PDF. Margin of 50pts inside
CropBox. Font size of title twice body font size. Null page labels added for CropBox. Font size of title twice body font size. Null page labels added for
TOC, others bumped up and so preserved. *) TOC, others bumped up and so preserved. *)
let typeset_table_of_contents ~font ~fontsize ~title pdf = let typeset_table_of_contents ~font ~fontsize ~title ~bookmark pdf =
let marks = Pdfmarks.read_bookmarks pdf in let marks = Pdfmarks.read_bookmarks pdf in
if marks = [] then (Printf.eprintf "No bookmarks, not making table of contents\n%!"; pdf) else if marks = [] then (Printf.eprintf "No bookmarks, not making table of contents\n%!"; pdf) else
let f, fs = (Pdftext.StandardFont (font, Pdftext.WinAnsiEncoding), fontsize) in let f, fs = (Pdftext.StandardFont (font, Pdftext.WinAnsiEncoding), fontsize) in
@ -100,4 +100,15 @@ let typeset_table_of_contents ~font ~fontsize ~title pdf =
in in
let labels' = label::map (fun l -> {l with Pdfpagelabels.startpage = l.Pdfpagelabels.startpage + toc_pages_len}) labels in let labels' = label::map (fun l -> {l with Pdfpagelabels.startpage = l.Pdfpagelabels.startpage + toc_pages_len}) labels in
Pdfpagelabels.write pdf labels'; Pdfpagelabels.write pdf labels';
pdf if bookmark then
let marks = Pdfmarks.read_bookmarks pdf in
let refnums = Pdf.page_reference_numbers pdf in
let newmark =
{Pdfmarks.level = 0;
Pdfmarks.text = Pdftext.pdfdocstring_of_utf8 title;
Pdfmarks.target = Pdfdest.XYZ (Pdfdest.PageObject (hd refnums), None, None, None);
Pdfmarks.isopen = false}
in
Pdfmarks.add_bookmarks (newmark::marks) pdf
else
pdf

View File

@ -1 +1 @@
val typeset_table_of_contents : font:Pdftext.standard_font -> fontsize:float -> title:string -> Pdf.t -> Pdf.t val typeset_table_of_contents : font:Pdftext.standard_font -> fontsize:float -> title:string -> bookmark:bool -> Pdf.t -> Pdf.t