Recent posts

#91
PDF Generation / Re: [Q] Python script written ...
Last post by Nermander - May 11, 2025, 07:54:32 PM
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.

Ok, so the first two and the last two pages end up on the cover?
#92
PDF Generation / Re: [Q] Python script written ...
Last post by jirib - May 11, 2025, 11:24:02 AM
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
...


IIUC, I need to introduce "slug area": CROP_OFFSET + CROP_LEN = <slug area rounded to next unit value>, eg. 2.117 mm + 5 mm = 7.117 mm, that is, 8mm.
#93
PDF Generation / Re: [Q] Python script written ...
Last post by jirib - May 11, 2025, 11:09:23 AM
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.

I will do it when all things are clear ;)
#94
PDF Generation / Re: [Q] Python script written ...
Last post by jirib - May 11, 2025, 11:07:27 AM
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
...

I defined these variables based on https://printedeasy.com/help/artwork-guides/setting-up-bleed-and-crop-marks, see the picture:



#95
PDF Generation / Re: [Q] Python script written ...
Last post by jirib - May 11, 2025, 10:57:27 AM
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?

Not really:

...
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)
...

So, it generates cover with 'cover_pairs'..., however, logically, it places crop marks and spine marks only on the first/outside cover page.
#96
PDF Generation / Re: [Q] Python script written ...
Last post by Nermander - May 11, 2025, 10:39:52 AM
Do 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?
#97
PDF Generation / Re: [Q] Python script written ...
Last post by jirib - May 11, 2025, 09:52:30 AM
I 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) ???
#98
PDF Generation / Re: [Q] Python script written ...
Last post by a.l.e - May 10, 2025, 02:56:25 PM
I can't say much about the calculation, sorry.

But if the calculations are validate by people who know more about spine marks than me, it might also be interesting to have a version that runs inside of Scribus and adds the marks on a dedicated layer.
#99
PDF Generation / [Q] Python script written to g...
Last post by jirib - May 10, 2025, 10:50:36 AM
Hi,
what do you think about this python script to create cover page from a PDF with spine marks ?

---%>---
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")
---%<---

#100
Scripts and Plugins / Re: Replacing selected text
Last post by prcek - May 10, 2025, 09:55:37 AM
Well, definitely I was checking that repo as well :-)
But if you don't know what exactly you're looking for it is more difficult to find it.
And as I wrote, the problem with find() can arise in case of a repetitive text parts.
Thank you again, getSelectedTextRange() seems to do what I need.