nupdf.core ========== .. py:module:: nupdf.core .. autoapi-nested-parse:: Core PDF and image manipulation utilities for nuPDF. This module provides three public functions: * :func:`read_pdf` — open a PDF or convert an image to PDF * :func:`rotate_pages` — rotate selected pages of a PDF * :func:`merge_pdfs` — merge multiple PDFs/images into one PDF Dependencies: ``pypdf`` for PDF I/O, ``Pillow`` for image conversion. .. rubric:: Example >>> from nupdf.core import merge_pdfs, rotate_pages >>> merge_pdfs(["scan_front.pdf", "scan_back.pdf"], "merged.pdf", recto_verso=True) >>> rotate_pages("merged.pdf", "merged_rotated.pdf", pages=[0], angle=90) Attributes ---------- .. autoapisummary:: nupdf.core.PathLike Functions --------- .. autoapisummary:: nupdf.core.read_pdf nupdf.core.rotate_pages nupdf.core.merge_pdfs Module Contents --------------- .. py:data:: PathLike .. py:function:: read_pdf(path: PathLike) -> pypdf.PdfReader Open *path* as a :class:`~pypdf.PdfReader`. If *path* is not a valid PDF — for example a JPEG, PNG, GIF, or RAW image — it is first converted to a single-page PDF saved next to the original file (with ``.pdf`` appended to its full name). The PdfReader for that converted file is then returned. :param path: Path to a PDF or a Pillow-readable image file. :returns: An open reader for the (possibly converted) PDF. :rtype: pypdf.PdfReader :raises FileNotFoundError: If *path* does not exist on disk. :raises ValueError: If the file cannot be opened as a PDF or as a Pillow image. .. rubric:: Examples >>> reader = read_pdf("document.pdf") >>> print(len(reader.pages)) 3 .. py:function:: rotate_pages(path: PathLike, savingpath: PathLike, pages: Optional[Sequence[int]] = None, angle: int = 90) -> None Rotate one or more pages of a PDF and write the result to *savingpath*. The rotation is **clockwise**. Only multiples of 90° are supported by the PDF specification; non-multiples are rounded down to the nearest 90°. Angles outside ``[0, 360)`` are normalised automatically. :param path: Input PDF or image file. :param savingpath: Destination path for the output PDF. Created or overwritten. :param pages: Sequence of **0-indexed** page numbers to rotate. When *None* (the default) every page is rotated. :param angle: Clockwise rotation angle in degrees. Non-multiples of 90 are truncated; values outside ``[0, 360)`` are normalised. :raises ValueError: If *path* cannot be opened as a PDF or image. :raises FileNotFoundError: If *path* does not exist. .. rubric:: Examples Rotate the first page 90° clockwise: >>> rotate_pages("input.pdf", "output.pdf", pages=[0], angle=90) Rotate all pages 180°: >>> rotate_pages("input.pdf", "output.pdf", angle=180) .. py:function:: merge_pdfs(pdffiles: Sequence[PathLike], savingpath: PathLike, recto_verso: bool = False, same_file: Optional[bool] = None, bookmark: bool = True) -> None Merge multiple PDF/image files into a single output PDF. :param pdffiles: Ordered list of PDF or image paths to include in the merge. :param savingpath: Destination path for the merged PDF. Created or overwritten. :param recto_verso: When *True* the pages of each source file are interleaved in a *zipper* pattern: the first half of the document is paired page-by-page with the second half. **Use-case:** scanning a double-sided document with a single-pass scanner. Scan all front pages into one run (pages 0 … n/2−1), flip the paper stack and scan the backs (pages n/2 … n−1). The resulting file has fronts then backs; enable *recto_verso* to interleave them into reading order. :param same_file: Only meaningful when *recto_verso* is *True*. Set to *True* when the front and back pages are stored in **two separate files** in *pdffiles*. The files are first concatenated normally, then the recto-verso interleaving is applied to the combined result. :param bookmark: When *True* (default) a named bookmark is added at the first page of each source document using the source filename stem as the title. :raises ValueError: If *pdffiles* is empty. .. rubric:: Examples Simple merge with bookmarks: >>> merge_pdfs(["chapter1.pdf", "chapter2.pdf"], "book.pdf") Recto-verso from a single combined scan file: >>> merge_pdfs(["both_sides.pdf"], "sorted.pdf", recto_verso=True) Recto-verso from two separate scan files (fronts then backs): >>> merge_pdfs(["fronts.pdf", "backs.pdf"], "sorted.pdf", ... recto_verso=True, same_file=True)