Page 1 of 1
Insert last page between every page (1-A-2-A-3-A)
Posted: Fri Mar 13, 2026 12:32 pm
by magnussandstrom
What is the best way to build a flow that inserts the last page between every page, regardless of how many pages the incoming PDF contains?
We often receive business cards as PDF files where the last page contains the back of the card, while the other pages contain the fronts with different people's contact details.
Re: Insert last page between every page (1-A-2-A-3-A)
Posted: Fri Mar 13, 2026 8:16 pm
by jan_suhr
Re: Insert last page between every page (1-A-2-A-3-A)
Posted: Sat Mar 14, 2026 6:50 am
by magnussandstrom
I can solve it, but it’s not pretty. I’m wondering how others have solved it, I guess that it’s quite common.
Re: Insert last page between every page (1-A-2-A-3-A)
Posted: Mon Mar 16, 2026 11:33 am
by magnussandstrom
I ended upp building a small app using Python.
Code: Select all
import argparse
import os
import shutil
import sys
import tempfile
from pathlib import Path
import fitz # PyMuPDF
EXIT_SUCCESS = 0
EXIT_USAGE_ERROR = 1
EXIT_INPUT_ERROR = 2
EXIT_PROCESSING_ERROR = 3
def info(message: str) -> None:
"""Write normal status messages to stdout."""
print(message)
def error(message: str) -> None:
"""Write error messages to stderr."""
print(message, file=sys.stderr)
def validate_input_path(path: Path) -> None:
if not path.exists():
raise FileNotFoundError(f"Input file does not exist: {path}")
if not path.is_file():
raise ValueError(f"Input is not a file: {path}")
if path.suffix.lower() != ".pdf":
raise ValueError(f"Input file must be a PDF: {path}")
def interleave_last_page(input_pdf: Path, output_pdf: Path) -> None:
validate_input_path(input_pdf)
output_pdf.parent.mkdir(parents=True, exist_ok=True)
temp_path = None
try:
with fitz.open(str(input_pdf)) as src:
if src.page_count < 3:
raise ValueError("Input PDF must contain at least 3 pages.")
last_page_index = src.page_count - 1
expected_output_pages = (src.page_count - 1) * 2
with fitz.open() as out:
metadata = src.metadata or {}
if metadata:
try:
out.set_metadata(metadata)
except Exception:
pass
for i in range(last_page_index):
out.insert_pdf(src, from_page=i, to_page=i)
out.insert_pdf(src, from_page=last_page_index, to_page=last_page_index)
if out.page_count != expected_output_pages:
raise RuntimeError(
f"Internal error: output has {out.page_count} pages "
f"(expected {expected_output_pages})."
)
fd, temp_name = tempfile.mkstemp(
prefix=output_pdf.stem + "_",
suffix=".tmp.pdf",
dir=str(output_pdf.parent),
)
os.close(fd)
temp_path = Path(temp_name)
out.save(str(temp_path))
shutil.move(str(temp_path), str(output_pdf))
temp_path = None
# SUCCESS LOG → STDOUT
info(f"INPUT={input_pdf}")
info(f"INPUT_PAGES={last_page_index + 1}")
info(f"OUTPUT={output_pdf}")
info(f"OUTPUT_PAGES={expected_output_pages}")
info("STATUS=OK")
finally:
if temp_path is not None and temp_path.exists():
try:
temp_path.unlink()
except Exception:
pass
def parse_args(argv=None):
parser = argparse.ArgumentParser(
description="Insert the last page between all previous pages in a PDF."
)
parser.add_argument("input_pdf", help="Path to input PDF")
parser.add_argument("output_pdf", help="Path to output PDF")
return parser.parse_args(argv)
def main(argv=None) -> int:
try:
args = parse_args(argv)
input_pdf = Path(args.input_pdf)
output_pdf = Path(args.output_pdf)
interleave_last_page(input_pdf, output_pdf)
return EXIT_SUCCESS
except SystemExit:
raise
except (FileNotFoundError, ValueError) as e:
error(f"ERROR={e}")
return EXIT_INPUT_ERROR
except Exception as e:
error(f"ERROR={e}")
return EXIT_PROCESSING_ERROR
if __name__ == "__main__":
sys.exit(main())
Re: Insert last page between every page (1-A-2-A-3-A)
Posted: Fri Apr 24, 2026 1:10 pm
by yosimo
magnussandstrom wrote: ↑Sat Mar 14, 2026 6:50 am
... I’m wondering how others have solved it...
Well, we do that right in Adobe Acrobat using a small JavaScript code.
Code: Select all
for (var i = this.numPages - 1; i > 0; i--) {
this.insertPages(i - 1, this.path, this.numPages - 1, this.numPages - 1);
}
this.deletePages(this.numPages - 1);
I don't have Switch, and I don't know if Switch supports JavaScript.
But it's amazing that Switch needs an external plugin that costs $100/year just for such a basic task.