Problems registering, no confirmation email - see http://wiki.scribus.net/canvas/Forums_Registration
Quote from: jirib on May 11, 2025, 10:57:27 AMSo, it generates cover with 'cover_pairs'..., however, logically, it places crop marks and spine marks only on the first/outside cover page.
Quote from: jirib on May 11, 2025, 11:07:27 AM...
CROP_OFFSET = 6 * pt
CROP_LINE_WIDTH = 0.2 * pt
CROP_LEN = 5 * mm
...
BLEED = 5 * mm
...
Quote from: a.l.e on May 10, 2025, 02:56:25 PM(...) it might also be interesting to have a version that runs inside of Scribus and adds the marks on a dedicated layer.
Quote from: jirib on May 11, 2025, 09:52:30 AMI even did not know how crop marks or spine marks should look like :/ I could not find an exact description. Maybe in the scribus source (for crop marks)
...
CROP_OFFSET = 6 * pt
CROP_LINE_WIDTH = 0.2 * pt
CROP_LEN = 5 * mm
...
BLEED = 5 * mm
...
Quote from: Nermander on May 11, 2025, 10:39:52 AMDo I understand it right, this script takes a PDF and make a cover of the first and last page?
So, with a 12 page PDF, pages 1 and 12 end up in a cover PDF (landscape, 2-up, with a spine between the pages) and the pages 2-11 end up in a "content only" PDF?
And the width of the spine is calculated based on the number of pages and an assumed page thickness of 0.083?
But what about the insides of the cover? Those will be blank?
...
cover_pairs = [
(reader.pages[total_pages - 1], reader.pages[0]),
(reader.pages[1], reader.pages[total_pages - 2])
]
...
# === Generate 2-page cover PDF
cover_writer = PdfWriter()
for i, (left, right) in enumerate(cover_pairs):
merged = PageObject.create_blank_page(None, TOTAL_WIDTH, TOTAL_HEIGHT)
if i == 0:
packet = BytesIO()
c = canvas.Canvas(packet, pagesize=(TOTAL_WIDTH, TOTAL_HEIGHT))
draw_marks(c, TOTAL_WIDTH, TOTAL_HEIGHT, spine_width)
c.showPage()
c.save()
packet.seek(0)
marks = PdfReader(packet).pages[0]
merged.merge_page(marks)
merged.merge_translated_page(left, tx=BLEED, ty=BLEED)
merged.merge_translated_page(right, tx=BLEED + A5_WIDTH + spine_width, ty=BLEED)
cover_writer.add_page(merged)
with open(cover_out, "wb") as f:
cover_writer.write(f)
...
---%>---
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm, inch
from reportlab.lib.colors import black
from pypdf import PdfReader, PdfWriter, PageObject
from io import BytesIO
from pathlib import Path
import sys
pt = inch / 72.0
CROP_OFFSET = 6 * pt
CROP_LINE_WIDTH = 0.2 * pt
CROP_LEN = 5 * mm
A5_WIDTH = 148.5 * mm
HEIGHT = 210 * mm
BLEED = 5 * mm
def draw_marks(c, total_width, total_height, spine_width):
c.setStrokeColor(black)
c.setLineWidth(CROP_LINE_WIDTH)
xL = BLEED
xR = total_width - BLEED
xCL = xL - CROP_OFFSET
xCR = xR + CROP_OFFSET
yB = BLEED
yT = total_height - BLEED
yCB = yB - CROP_OFFSET
yCT = yT + CROP_OFFSET
c.line(xL, yCT, xL, yCT + CROP_LEN)
c.line(xR, yCT, xR, yCT + CROP_LEN)
c.line(xCL - CROP_LEN, yT, xCL, yT)
c.line(xCR, yT, xCR + CROP_LEN, yT)
c.line(xL, yCB, xL, yCB - CROP_LEN)
c.line(xR, yCB, xR, yCB - CROP_LEN)
c.line(xCL - CROP_LEN, yB, xCL, yB)
c.line(xCR, yB, xCR + CROP_LEN, yB)
xS1 = BLEED + A5_WIDTH
xS2 = xS1 + spine_width
for x in [xS1, xS2]:
c.line(x, yCB, x, yCB - CROP_LEN)
c.line(x, yCT, x, yCT + CROP_LEN)
if len(sys.argv) < 2:
print("Usage: python generate_cover.py input.pdf")
sys.exit(1)
input_path = Path(sys.argv[1])
reader = PdfReader(str(input_path))
total_pages = len(reader.pages)
if total_pages < 4:
raise ValueError("❌ PDF must have at least 4 pages.")
cover_pairs = [
(reader.pages[total_pages - 1], reader.pages[0]),
(reader.pages[1], reader.pages[total_pages - 2])
]
cover_indices = {0, 1, total_pages - 2, total_pages - 1}
content_page_count = total_pages - 4
spine_width = round(content_page_count * 0.083, 3) * mm
TOTAL_WIDTH = 2 * A5_WIDTH + spine_width + 2 * BLEED
TOTAL_HEIGHT = HEIGHT + 2 * BLEED
# ✅ Output paths
base = input_path.with_suffix('')
cover_out = base.with_name(base.name + "_cover_final.pdf")
content_out = base.with_name(base.name + "_content.pdf")
# === Generate 2-page cover PDF
cover_writer = PdfWriter()
for i, (left, right) in enumerate(cover_pairs):
merged = PageObject.create_blank_page(None, TOTAL_WIDTH, TOTAL_HEIGHT)
if i == 0:
packet = BytesIO()
c = canvas.Canvas(packet, pagesize=(TOTAL_WIDTH, TOTAL_HEIGHT))
draw_marks(c, TOTAL_WIDTH, TOTAL_HEIGHT, spine_width)
c.showPage()
c.save()
packet.seek(0)
marks = PdfReader(packet).pages[0]
merged.merge_page(marks)
merged.merge_translated_page(left, tx=BLEED, ty=BLEED)
merged.merge_translated_page(right, tx=BLEED + A5_WIDTH + spine_width, ty=BLEED)
cover_writer.add_page(merged)
with open(cover_out, "wb") as f:
cover_writer.write(f)
# === Generate content-only PDF
content_writer = PdfWriter()
for i in range(total_pages):
if i not in cover_indices:
content_writer.add_page(reader.pages[i])
with open(content_out, "wb") as f:
content_writer.write(f)
# === Summary
print("✅ Cover PDF: ", cover_out.name)
print("✅ Content PDF: ", content_out.name)
print("📏 Spine width: ", round(spine_width / mm, 3), "mm")
---%<---