Skip to content

Instantly share code, notes, and snippets.

@omo
Created June 25, 2025 15:55
Show Gist options
  • Save omo/3fab29c0c5371d8157d08bce50cd8455 to your computer and use it in GitHub Desktop.
Save omo/3fab29c0c5371d8157d08bce50cd8455 to your computer and use it in GitHub Desktop.
concatinate pdf files with toc
#!/usr/bin/env python3
import sys
import os
from pypdf import PdfWriter, PdfReader
def concatenate_pdfs(output_path, input_paths):
"""
Concatenate multiple PDF files into a single PDF file with bookmarks.
Args:
output_path (str): Path to the output PDF file
input_paths (list): List of paths to input PDF files
"""
writer = PdfWriter()
current_page = 0
# Add each PDF to the output with bookmarks
for pdf_file in input_paths:
try:
# Get the basename of the file to use as bookmark title
bookmark_title = os.path.basename(pdf_file)
# Read the PDF file
reader = PdfReader(pdf_file)
page_count = len(reader.pages)
# Add pages from this PDF to the output
for page_num in range(page_count):
writer.add_page(reader.pages[page_num])
# Add a bookmark pointing to the first page of this PDF
writer.add_outline_item(bookmark_title, current_page)
# Update the current page count
current_page += page_count
except Exception as e:
print(f"Error processing {pdf_file}: {e}", file=sys.stderr)
return False
try:
# Write the output PDF
with open(output_path, "wb") as output_file:
writer.write(output_file)
return True
except Exception as e:
print(f"Error writing to {output_path}: {e}", file=sys.stderr)
return False
def main():
"""
Main function to handle command-line arguments and call concatenate_pdfs.
"""
if len(sys.argv) < 3:
print("Usage: pdfcat.py output.pdf input1.pdf input2.pdf [input3.pdf ...]", file=sys.stderr)
sys.exit(1)
output_path = sys.argv[1]
input_paths = sys.argv[2:]
# Check if all input files exist
for pdf_file in input_paths:
try:
with open(pdf_file, 'rb') as f:
pass
except FileNotFoundError:
print(f"Error: File not found: {pdf_file}", file=sys.stderr)
sys.exit(1)
success = concatenate_pdfs(output_path, input_paths)
if success:
print(f"Successfully created {output_path} with bookmarks for each input PDF")
sys.exit(0)
else:
sys.exit(1)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment