diff --git a/cpdf.ml b/cpdf.ml index 191a426..ebf15d1 100644 --- a/cpdf.ml +++ b/cpdf.ml @@ -1317,40 +1317,6 @@ let get_bookmark_name pdf marks splitlevel n _ = | {Pdfmarks.text = title}::_ -> remove_unsafe_characters title | _ -> "" -(* @F means filename without extension *) -(* @N means sequence number with no padding *) -(* @S means start page of this section *) -(* @E means end page of this section *) -(* @B means bookmark name at start page *) -let process_others marks pdf splitlevel filename sequence startpage endpage s = - let rec procss prev = function - | [] -> rev prev - | '@'::'F'::t -> procss (rev (explode filename) @ prev) t - | '@'::'N'::t -> procss (rev (explode (string_of_int sequence)) @ prev) t - | '@'::'S'::t -> procss (rev (explode (string_of_int startpage)) @ prev) t - | '@'::'E'::t -> procss (rev (explode (string_of_int endpage)) @ prev) t - | '@'::'B'::t -> procss (rev (explode (get_bookmark_name pdf marks splitlevel startpage pdf)) @ prev) t - | h::t -> procss (h::prev) t - in - implode (procss [] (explode s)) - -let name_of_spec marks (pdf : Pdf.t) splitlevel spec n filename startpage endpage = - let fill l n = - let chars = explode (string_of_int n) in - if length chars > l - then implode (drop chars (length chars - l)) - else implode ((many '0' (l - length chars)) @ chars) - in - let chars = explode spec in - let before, including = cleavewhile (neq '%') chars in - let percents, after = cleavewhile (eq '%') including in - if percents = [] - then - process_others marks pdf splitlevel filename n startpage endpage spec - else - process_others marks pdf splitlevel filename n startpage endpage - (implode before ^ fill (length percents) n ^ implode after) - (* Find the stem of a filename *) let stem s = implode (rev (tail_no_fail (dropwhile (neq '.') (rev (explode (Filename.basename s)))))) diff --git a/cpdf.mli b/cpdf.mli index b69f771..e28e4d7 100644 --- a/cpdf.mli +++ b/cpdf.mli @@ -80,22 +80,6 @@ val validate_pagespec : string -> bool val parse_pagespec_without_pdf : string -> int list -(** [name_of_spec printf marks pdf splitlevel spec n filename startpage -endpage] makes format substitutions in [spec] to make an output file name: - -{ul -{- @F will be replaced by [filename]} -{- @N will be replace by the current sequence number [n], [n+1] etc.} -{- @S will be replace by the start page} -{- @E will be replace by the end page} -{- @B will be replace by the bookmark name in [marks] at the given level [splitlevel]} -} -[printf] is undocumented and should be set to [false]. -*) -val name_of_spec : Pdfmarks.t list -> Pdf.t -> int -> string -> int -> string -> int -> int -> string - -(** {2 Compress and Decompress} *) - (** Compresses all streams in the PDF document which are uncompressed, using /FlateDecode, leaving out metadata. If the PDF is encrypted, does nothing. *) val recompress_pdf : Pdf.t -> Pdf.t diff --git a/cpdfcommand.ml b/cpdfcommand.ml index f3756ce..ed13dfe 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -2515,16 +2515,42 @@ let get_bookmark_name pdf marks splitlevel n _ = (* @E means end page of this section *) (* @B means bookmark name at start page *) let process_others marks pdf splitlevel filename sequence startpage endpage s = - let rec procss prev = function - | [] -> rev prev - | '@'::'F'::t -> procss (rev (explode filename) @ prev) t - | '@'::'N'::t -> procss (rev (explode (string_of_int sequence)) @ prev) t - | '@'::'S'::t -> procss (rev (explode (string_of_int startpage)) @ prev) t - | '@'::'E'::t -> procss (rev (explode (string_of_int endpage)) @ prev) t - | '@'::'B'::t -> procss (rev (explode (get_bookmark_name pdf marks splitlevel startpage pdf)) @ prev) t - | h::t -> procss (h::prev) t + let rec find_ats p = function + '@'::r -> find_ats (p + 1) r + | r -> (p, r) in - implode (procss [] (explode s)) + let string_of_int_width w i = + if w < 0 then raise (Pdf.PDFError "width of field too narrow") + else if w > 8 then raise (Pdf.PDFError "width of field too broad") else + let formats = + [|format_of_string "%i"; + format_of_string "%i"; + format_of_string "%02i"; + format_of_string "%03i"; + format_of_string "%04i"; + format_of_string "%05i"; + format_of_string "%06i"; + format_of_string "%07i"; + format_of_string "%08i"|] + in + Printf.sprintf formats.(w) i + in + let rec procss prev = function + | [] -> rev prev + | '@'::'F'::t -> procss (rev (explode filename) @ prev) t + | '@'::'N'::t -> + let width, rest = find_ats 0 t in + procss (rev (explode (string_of_int_width width sequence)) @ prev) rest + | '@'::'S'::t -> + let width, rest = find_ats 0 t in + procss (rev (explode (string_of_int_width width startpage)) @ prev) rest + | '@'::'E'::t -> + let width, rest = find_ats 0 t in + procss (rev (explode (string_of_int_width width endpage)) @ prev) rest + | '@'::'B'::t -> procss (rev (explode (get_bookmark_name pdf marks splitlevel startpage pdf)) @ prev) t + | h::t -> procss (h::prev) t + in + implode (procss [] (explode s)) let name_of_spec marks (pdf : Pdf.t) splitlevel spec n filename startpage endpage = let fill l n = @@ -2739,7 +2765,7 @@ let extract_images pdf range stem = (let names = map (function n -> - let r = Cpdf.name_of_spec [] pdf 0 ("p" ^ string_of_int pnum ^ "_" ^ stem) n "" 0 0 in r) + let r = name_of_spec [] pdf 0 ("p" ^ string_of_int pnum ^ "_" ^ stem) n "" 0 0 in r) (indx images) in iter2 (write_image pdf page.Pdfpage.resources) names images)) @@ -2758,7 +2784,6 @@ let getencryption pdf = | Some (Pdfwrite.AES256bitISO true) -> "256bit AES ISO, Metadata encrypted" | Some (Pdfwrite.AES256bitISO false) -> "256bit AES ISO, Metadata not encrypted" - (* If a cropbox exists, make it the mediabox. If not, change nothing. *) let copy_cropbox_to_mediabox pdf range = Cpdf.process_pages diff --git a/cpdfmanual.tex b/cpdfmanual.tex index 47531f0..a84c310 100644 --- a/cpdfmanual.tex +++ b/cpdfmanual.tex @@ -16,6 +16,7 @@ %FIXME: Document -remove-clipping %FIXME: Document new -list-spot-colours %FIXME: Document new -pad-multiple-before +%FIXME: Document new @N@@@ @E@@@, @S@@@ options \documentclass{book} \usepackage{palatino}