Nummerierungen vornehmen

Antworten
waldbaer59
Beiträge: 14
Registriert: Sa 7. Nov 2020, 16:05

Nummerierungen vornehmen

Beitrag von waldbaer59 »

Hallo zusammen,

ich habe ein kleines Skript geschrieben, mit dem man in Texten Nummerierungen vornehmen lassen kann. Ein Beispiel für dessen Anwendung wäre etwa die Nummerierung von Bildtafeln in einem Dokument. Aktuell habe ich 5 Zähler vorgesehen, die wahlweise numerisch, römisch (große Buchstaben) und römisch mit kleinen Buchstaben durchzählen. Das Skript durchsucht alle Textfelder und dort nach Zeichenketten des Typs "§1§" bis "§5§" (die Ziffer zwischen den Paragraphenzeichen ist die Zählernummer). Beginnend mit der Zahl eins wird dann bei jeder Fundstelle der entsprechende Zähler um 1 hochgesetzt und in den Text befördert.

Den Gedanken zu einem solchen Skript hatte ich schon länger, aber die leidige Faulheit... ;) . Jetzt habe ich es doch einmal umgesetzt. Das Coding findet sich im Anschluß. Es ist ziemlich einfach (um nicht zu sagen primitiv), aber ich fange gerade erst an mich etwas in die Grundlagen einzuarbeiten.

Falls es Anregungen gibt: gerne!

Wichtig: das Skript verändert natürlich das aktuelle Dokument im Speicher. Daher muss man ein Dokument geöffnet haben. Außerdem sind die Zählerkennzeichen, z.B. "§1§", hinterher durch die konkrete Nummmerierung überschrieben. Es ist also erforderlich, dass man das Dokument ohne die ersetzten Zählerkennzeichen vorher separat abspeichert, damit man bei späteren Änderungen noch darauf zurückgreifen kann. Wenn man später ein zu nummerierendes Objekt einfügt oder löscht muss man ja das Skript wieder ablaufen lassen können.

VLG
Stephan

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

try:
    from scribus import *
except ImportError:
    print("This Python script is written for the Scribus \
      scripting interface.")
    print("It can only be run from within Scribus.")
    sys.exit(1)

try:
    import tkinter as tk
    from tkinter import *  # python 3
    from tkinter import messagebox, filedialog, font
    from tkinter import ttk
except ImportError:
    print("This script requires Python Tkinter properly installed.")
    messageBox('Script failed',
               'This script requires Python Tkinter properly installed.',
               ICON_CRITICAL)
    sys.exit(1)

# ----- Zeichenfolge/n nach der/denen in den Textfeldern gesucht werden soll
such_string1 = "§1§"
such_string2 = "§2§"
such_string3 = "§3§"
such_string4 = "§4§"
such_string5 = "§5§"

# ----- Nummerierungs-Kennzeichen (1 = int, 2 = römisch groß, 3 = römisch klein)
# ----- Vorgaben hier nur pro forma. Die eigentliche Belegung findet unten bei der 
# ----- Abarbeitung der Eingabemaske statt.
num_kennz1 = 1
num_kennz2 = 1
num_kennz3 = 1
num_kennz4 = 2
num_kennz5 = 3

# ----- Zähler für Nummern
nummer1 = 0
nummer2 = 0
nummer3 = 0
nummer4 = 0
nummer5 = 0


# ----- Eingabemaske aufbauen und prozessieren
master = Tk()


# ----- Numerierung auch für römische Ziffern vorsehen. Daher Umrechnung definieren.
def int_to_roman(num):
    val = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
    syb = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]
    roman_num = ''
    i = 0
    while num > 0:
        for j in range(num // val[i]):
            roman_num += syb[i]
            num -= val[i]
        i += 1
    return roman_num


# ----- Funktion für die Umrechnung in den jeweiligen Nummern-String
def num_str(zahl, num_kennz):
    # ----- arabische Ziffern sind der Standardwert
    if num_kennz < 1 or num_kennz > 3:
        num_kennz = 1
    # ----- arabische Ziffern
    if num_kennz == 1:
        zahl_als_str = str(zahl)
    # ----- römische Ziffern (groß)
    elif num_kennz == 2:
        zahl_als_str = int_to_roman(zahl)
    # ----- römische Ziffern (klein)
    elif num_kennz == 3:
        zahl_als_str = int_to_roman(zahl)
        zahl_als_str = zahl_als_str.lower()
    else:
        pass
    return zahl_als_str


# ----- Feld für Textfeld_Namen initialisieren
# textfeld = ""

# ----- allg. Funktion zur Nummern-Ersetzung
# ----- Suchstring 1
def number_replace1(textfeld, textfeld_name):
    global nummer1, such_string1, num_kennz1
    position = textfeld.find(such_string1)
    if position >= 0:
        nummer1 += 1
        selectText(position, 3, textfeld_name)
        deleteText(textfeld_name)
        insertText(num_str(nummer1, num_kennz1), position, textfeld_name)


# ----- Suchstring 2
def number_replace2(textfeld, textfeld_name):
    global nummer2, such_string2, num_kennz2
    position = textfeld.find(such_string2)
    if position >= 0:
        nummer2 += 1
        selectText(position, 3, textfeld_name)
        deleteText(textfeld_name)
        insertText(num_str(nummer2, num_kennz2), position, textfeld_name)


# ----- Suchstring 3
def number_replace3(textfeld, textfeld_name):
    global nummer3, such_string3, num_kennz3
    position = textfeld.find(such_string3)
    if position >= 0:
        nummer3 += 1
        selectText(position, 3, textfeld_name)
        deleteText(textfeld_name)
        insertText(num_str(nummer3, num_kennz3), position, textfeld_name)


# ----- Suchstring 4
def number_replace4(textfeld, textfeld_name):
    global nummer4, such_string4, num_kennz4
    position = textfeld.find(such_string4)
    if position >= 0:
        nummer4 += 1
        selectText(position, 3, textfeld_name)
        deleteText(textfeld_name)
        insertText(num_str(nummer4, num_kennz4), position, textfeld_name)


# ----- Suchstring 5
def number_replace5(textfeld, textfeld_name):
    global nummer5, such_string5, num_kennz5
    position = textfeld.find(such_string5)
    if position >= 0:
        nummer5 += 1
        selectText(position, 3, textfeld_name)
        deleteText(textfeld_name)
        insertText(num_str(nummer5, num_kennz5), position, textfeld_name)


# ----- Große Bearbeitungsfunktion
def rest_abarbeiten():
    global num_kennz1, num_kennz2, num_kennz3, num_kennz4, num_kennz5
    num_kennz1 = int(e1.get())
    num_kennz2 = int(e2.get())
    num_kennz3 = int(e3.get())
    num_kennz4 = int(e4.get())
    num_kennz5 = int(e5.get())
    # ----- Anzahl der Seiten im Dokument ermitteln
    seiten_anzahl = pageCount()
    # ----- die Seiten durcharbeiten
    for i in range(1, seiten_anzahl + 1):
        gotoPage(i)
        element_liste = getPageItems()
        # ----- Elemente der Seite durchsehen
        for j in (element_liste):
            # ----- Wenn Textrahmen (also Typ 4)
            if j[1] == 4:
                # ----- Ggf Ersetzung Typ 1 im String vornehmen und zurückschreiben
                textfeld = getFrameText(j[0])
                number_replace1(textfeld, j[0])
                # ----- Ggf Ersetzung Typ 2 im String vornehmen und zurückschreiben
                textfeld = getFrameText(j[0])
                number_replace2(textfeld, j[0])
                # ----- Ggf Ersetzung Typ 3 im String vornehmen und zurückschreiben
                textfeld = getFrameText(j[0])
                number_replace3(textfeld, j[0])
                # ----- Ggf Ersetzung Typ 4 im String vornehmen und zurückschreiben
                textfeld = getFrameText(j[0])
                number_replace4(textfeld, j[0])
                # ----- Ggf Ersetzung Typ 5 im String vornehmen und zurückschreiben
                textfeld = getFrameText(j[0])
                number_replace5(textfeld, j[0])
    # ----- Fenster schließen
    master.destroy()


# ----- ****************************************************************************
# ----- ****************************************************************************
# ----- ****************************************************************************
master.title("Numerierungs-Skript")
Label(master, text="Numerierungsart wählen: ", pady=15).grid(row=0)
Label(master, text="num", padx=20).grid(row=0, column=1)
Label(master, text="RÖM", padx=20).grid(row=0, column=2)
Label(master, text="röm", padx=20).grid(row=0, column=3)
Label(master, text="Zähler 1 : ").grid(row=1)
Label(master, text="Zähler 2 : ").grid(row=2)
Label(master, text="Zähler 3 : ").grid(row=3)
Label(master, text="Zähler 4 : ").grid(row=4)
Label(master, text="Zähler 5 : ").grid(row=5)

# ----- Eingabefeldnamen festlegen
e1 = IntVar()
e2 = IntVar()
e3 = IntVar()
e4 = IntVar()
e5 = IntVar()

# ----- Vorgabewerte belegen
e1.set(1) # ----- numerisch
e2.set(1) # ----- numerisch
e3.set(1) # ----- numerisch
e4.set(2) # ----- römisch groß
e5.set(3) # ----- römisch klein

# ----- Ausgabe im Fenster festlegen
# ----- Zähler 1
Radiobutton(master, text="", variable=e1, value=1).grid(row=1, column=1)
Radiobutton(master, text="", variable=e1, value=2).grid(row=1, column=2)
Radiobutton(master, text="", variable=e1, value=3).grid(row=1, column=3)
# ----- Zähler 2
Radiobutton(master, text="", variable=e2, value=1).grid(row=2, column=1)
Radiobutton(master, text="", variable=e2, value=2).grid(row=2, column=2)
Radiobutton(master, text="", variable=e2, value=3).grid(row=2, column=3)
# ----- Zähler 3
Radiobutton(master, text="", variable=e3, value=1).grid(row=3, column=1)
Radiobutton(master, text="", variable=e3, value=2).grid(row=3, column=2)
Radiobutton(master, text="", variable=e3, value=3).grid(row=3, column=3)
# ----- Zähler 4
Radiobutton(master, text="", variable=e4, value=1).grid(row=4, column=1)
Radiobutton(master, text="", variable=e4, value=2).grid(row=4, column=2)
Radiobutton(master, text="", variable=e4, value=3).grid(row=4, column=3)
# ----- Zähler 5
Radiobutton(master, text="", variable=e5, value=1).grid(row=5, column=1)
Radiobutton(master, text="", variable=e5, value=2).grid(row=5, column=2)
Radiobutton(master, text="", variable=e5, value=3).grid(row=5, column=3)

# ----- Buttons für Abbruch und Start festlegen
Button(master, text='Abbruch', command=master.destroy).grid(row=7, column=0, sticky=W, pady=10)
Button(master, text='Start', command=rest_abarbeiten).grid(row=7, column=1, sticky=W, pady=10)

mainloop()
Benutzeravatar
utnik
Beiträge: 886
Registriert: Sa 31. Jan 2015, 08:48

Re: Nummerierungen vornehmen

Beitrag von utnik »

hallo stephan
waldbaer59 hat geschrieben: Sa 4. Feb 2023, 16:12…Außerdem sind die Zählerkennzeichen, z.B. "§1§", hinterher durch die konkrete Nummmerierung überschrieben. Es ist also erforderlich, dass man das Dokument ohne die ersetzten Zählerkennzeichen vorher separat abspeichert, damit man bei späteren Änderungen noch darauf zurückgreifen kann. Wenn man später ein zu nummerierendes Objekt einfügt oder löscht muss man ja das Skript wieder ablaufen lassen können.
wäre es nicht sinnvoller, nach einer (wahllosen) zeichenkette in einem separaten zeichenformat zu suchen und die gefundenen zeichenketten durch die entsprechende nummerierung zu ersetzen, wobei das zeichenformat beibehalten würde? damit könnte das script bei bedarf immer wieder auf das selbe dokument angewendet werden…

gruss
utnik
waldbaer59
Beiträge: 14
Registriert: Sa 7. Nov 2020, 16:05

Re: Nummerierungen vornehmen

Beitrag von waldbaer59 »

Eine interessante Idee. Ich schau mir das die Tage genauer an. In diesem speziellen Zeichenformat könnte man dann auch Befehle hinterlegen um einzelne Zähler zurückzusetzen oder auf einen expliziten Wert zu legen (um nicht ausdrücklich bei 1 beginnen zu müssen). Genausogut wäre zu überlegen eine Anweisung zu codieren um einen Feldwert auszugeben ohne ihn hochzuzählen. Damit könnte man sogar mehrstufige Nummerierungen realisieren.
Ich sehe eine steile Lernkurve auf mich zukommen....*schaluck* :roll:

VLG
Stephan
Antworten