Recent posts

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

#12
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.
#13
Features / Re: Feature: Paste formatting
Last post by a.l.e - May 10, 2025, 09:28:53 AM
The plan is (probably) to have a creation of styles based on the current selection and then allow to apply the style with the keyboard.

We're not that far from it : - )

Once we have that, it should be easy to also add a copy paste for text formatting, but -- personally -- i'd prefer not to have the feature (most people will not find it, and those who find it are not encouraged to go for a better workflow)
#14
Scripts and Plugins / Re: Replacing selected text
Last post by a.l.e - May 10, 2025, 08:18:30 AM
Now that you say it, I have the feeling that I already have used it...

I did a quick check and found this:


https://github.com/aoloe/scribus-script-repository/blob/master/sort_lines/sort_lines.py

It does not seem to do what it should, but it does get the text selection and it even provides a polyfill : - )
#15
Scripts and Plugins / Re: Replacing selected text
Last post by prcek - May 10, 2025, 06:44:32 AM
Thank you very much!
It was really weird to me nobody needed it before. And I didn't find it in any script I checked

I was looking for it in output of
import scribus
help(scribus)

I run it on 1.6.1 (appimage) and it is missing there (checked right now). Could it be the reason it is missing in your generated doc?

It is present in 1.6.3 and 1.6.4. help, though.
#16
Features / Feature: Paste formatting
Last post by transnomadic - May 09, 2025, 08:11:11 PM
I would like the ability to apply the formatting or character style to any hi-lighted text or object from the last text or object that I've copied to my clipboard. The formatting or style would be applied either through a special shortcut (CTRL + SHIFT + V) or through an Edit > Paste format menu item.
#17
Features / Re: Shortcuts for Styles and S...
Last post by a.l.e - May 09, 2025, 06:17:06 PM
it's here:

https://bugs.scribus.net/view.php?id=17162

the patch waits for a good shortcut for being applied
#18
Features / Re: Shortcuts for Styles and S...
Last post by transnomadic - May 09, 2025, 06:14:10 PM
I would love to see support for assigning keyboard shortcuts to styles.

I'm typesetting a book right now, and applying styles takes a considerable amount of my time. Anything to speed that process would make me happier.
#19
Scripts and Plugins / Re: Replacing selected text
Last post by a.l.e - May 09, 2025, 05:06:23 PM
It's

scribus.getSelectedTextRange()
... No idea why it's not in my documentation.
... I guess it's time to fix the script that generates it and do an update!
#20
Scripts and Plugins / Replacing selected text
Last post by prcek - May 09, 2025, 03:28:12 PM
Hello everyone.

I'm trying to write a script that gets a selected text from a frame, changes it and replaces the original text by the new one.

What I cannot find out is how can I get the selection's start position to insert the new text at.

Here is very simplified version of my script, that should put selected text into parentheses.
It expects a text in a text frame selected.
Of course if you select text from start it will work.

import scribus

frame = scribus.getSelectedObject()
txt = scribus.getAllText(frame)
txt = '(' + txt + ')'
scribus.deleteText(frame)

position = 0
scribus.insertText(txt, position, frame)

scribus.layoutTextChain(frame)
scribus.setRedraw(True)
scribus.docChanged(True)

I want to avoid workarounds like getting the selected text and search it to get it's position as there is no certainty it is unique.

Is there any function like getTextSelection([name]) or similar?