Neues Modul lib/pdf_extract.py fuer die Volltext-Konvertierung der 5 Hauptanleitungen, behebt die Qualitaetsprobleme der ersten Version: - Doppelte Nummerierung entfernt: PDF-Gliederungsnummer wird nur fuer die Ueberschriften-Ebene ausgewertet, im RST-Text weggelassen (Sphinx nummeriert) - Bilder positionsbasiert (bbox) extrahiert und als .. figure:: mit Caption an der richtigen Textstelle referenziert (625 Refs, 0 fehlende Bilder) - Fliesstext zu Absaetzen zusammengefuehrt statt je PDF-Zeile ein Absatz - Aufzaehlungen als RST-Listen (Bullet-only-Zeilen mit Folgezeile gemergt, zusammengelaufene Bullets aufgesplittet) - Aenderungshistorie-/Dokumentinfo-Tabellen und TOC-Seiten uebersprungen - Symbolfont-Zeichen (PUA) auf Unicode gemappt fortna_convert_chapters.py: nutzt pdf_extract statt extract_products, lesbare Dokumenttitel je Kapitel, Verzeichnislisten fuellen Kapitel ohne DE-Quelle mit vorhandenen Fremdsprachen (Ersatzteilliste EN). build_index.py / conf.py: Fremd-Altdateien aus dem Build ausgeschlossen. Alte Test-.rst aus fruehen convert_to_rst.py-Laeufen entfernt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
17 KiB
Konzept: Fortna-Extraktion nach chapters/ + Projektordner fortna/
Status: Umgesetzt (erster vollständiger Durchlauf inkl. PDF-Build). Antworten aus der Rückfragerunde sind eingearbeitet (siehe Abschnitt "Entscheidungen"). Der tatsächliche Ist-Stand ist unten unter "Umsetzung / Ist-Stand" dokumentiert.
Umsetzung / Ist-Stand
Implementiert wurden vier Python-Skripte in lib/ mit bin/-Wrappern (.bat + .sh):
| Skript | Zweck | Wrapper |
|---|---|---|
lib/fortna_inventory.py |
Scannt das Rohmaterial, ordnet jede Datei Sprache + Zielkapitel + Aktion zu, schreibt results/fortna_inventory.json. |
bin/fortna_inventory.* |
lib/fortna_convert_chapters.py |
Volltext+Bilder für die 5 DE-Hauptanleitungen, Verzeichnislisten (index.de.rst) für alle übrigen Kapitel. --dry-run (Default) / --apply. |
bin/fortna_convert_chapters.* |
lib/fortna_init_project.py |
Legt projekte/fortna/ an (anlage.json, overrides/, images/, README.md). |
bin/fortna_init_project.* |
lib/build_index.py |
Generiert index.rst mit toctrees aus allen chapters/**/*.de.rst. |
(in build_pdf.*) |
bin/build_pdf.* |
Kompletter PDF-Build: index → sphinx-build -b latex → latexmk -lualatex. |
— |
Ergebnis des ersten Laufs:
- 5 Hauptanleitungen volltextig konvertiert (Betriebs-/Wartungsanleitung, Funktionsbeschreibung ILS/OMNIFLO/LoadingLoop), zusammen ~13.500 Textblöcke + mehrere Hundert entduplizierte Bilder.
- 9 Verzeichnislisten erzeugt (Zertifikate, Lieferantendoku nach Gewerk, Notstopp, Prüfberichte).
projekte/fortna/mitanlage.json-Platzhalter angelegt.- Vollständiger PDF-Build erfolgreich:
_build/latex/Fortna_Dokumentation_DE.pdf, ~670 Seiten,latexmk-Exit 0, keine LaTeX-Fehler.
Umgebung / Build-Voraussetzungen (bereits erfüllt)
- Sphinx 9.1.0 + myst-parser 5.1.0 im
.venv(ergänzt inrequirements.txt). - LaTeX: MiKTeX unter
C:\Program Files\MiKTeX\(lualatex/latexmk vorhanden). conf.pyerzeugt: LaTeX-Engine lualatex, babel statt polyglossia (polyglossia 2.13 wirft unter lualatex einen bidi-Fehler),iconpackage=none(FontAwesome7 in MiKTeX bricht unter lualatex ab). Beides inconf.pykommentiert.
Extraktion: neues Modul lib/pdf_extract.py
Die Volltext-Konvertierung der 5 Hauptanleitungen läuft über das neue Modul
lib/pdf_extract.py (extract_manual()), das gegenüber der ersten Version deutlich
sauberere .rst erzeugt:
- Keine doppelte Nummerierung mehr: Die im PDF vorhandene Gliederungsnummer (z. B. „1.7 Wichtige Informationen") wird nur zur Bestimmung der Überschriften-Ebene ausgewertet und im RST-Text entfernt. Sphinx/LaTeX nummeriert selbst → vorher „3.2.1 1.1 Wichtige Informationen", jetzt nur noch „3.2.1 Wichtige Informationen".
- Überschriften-Erkennung nur bei führender PDF-Gliederungsnummer (kein „fett allein"), damit Tabellenzellen nicht fälschlich zu Überschriften werden.
- Bilder positionsbasiert extrahiert und referenziert: pro Seite werden Text und Bilder
nach Y-Position verwoben; jedes Bild wird als
.. figure::mit korrektem Pfad und – falls vorhanden – der folgenden „Abbildung N: …"-Zeile als Caption eingebaut. (625 figure-Refs, 0 fehlende Bilddateien.) Duplikate werden per MD5 entfernt, Titelseiten-Deko und Vollseiten-Hintergründe herausgefiltert. - Fließtext zu Absätzen zusammengeführt: PDF-Zeilenumbrüche werden nicht mehr zu je einem Absatz; zusammenhängende Zeilen bilden einen Absatz, Satzende beendet ihn.
- Aufzählungen als RST-Listen: einzeln stehende Bullet-Zeichen werden mit der Folgezeile
zusammengeführt, in eine Zeile zusammengelaufene Bullets aufgesplittet →
--Listenpunkte. - Änderungshistorie-/Dokumentinfo-Tabellen am Dokumentanfang werden übersprungen (zerfielen vorher in sinnlose Einzelzellen), ebenso Inhaltsverzeichnis-Seiten und Kopf-/Fußzeilen.
Behobene Extraktionsprobleme
- Symbolfont-Zeichen (Wingdings/Symbol Private-Use-Area, z. B. Aufzählungs-Bullet U+F0B7):
via
clean_pua()auf echte Unicode-Zeichen (•, →, ✓) gemappt, restliche PUA-Zeichen entfernt. Vorher erschienen leere Kästchen im PDF. (Inlib/pdf_extract.py; die Variante inextract_products.pybleibt für die Produktprogramm-Extraktion bestehen.) - Fremd-Altdateien aus früheren
convert_to_rst.py-Testläufen (NORD-Getriebe/-Motor im Anhang, alte Risikobewertung/Contents/Konfig/Ersatzteile-Volltexte) wurden entfernt; die betroffenen Kapitel liegen konzeptkonform als Verzeichnisliste vor.
Bekannte Restpunkte (nicht Teil des Auftrags-Scopes)
- Zwei Fremd-Altdateien aus früheren
convert_to_rst.py-Testläufen sind noch im Baum und vom Build ausgeschlossen (conf.py+build_index.pySKIP-Liste):02_sicherheit/risikobewertung/rb_fortna_...de.rst(unvollständiger Bildbestand) und00_inhaltsverzeichnis/contens_obsah_...de.rst(keine RST-Überschrift). Zwei weitere Altdateien in10_anhang/(Motor/Getriebe) sind noch im toctree und zeigen typische Extraktionsartefakte – bei Bedarf mitfortna_convert_chapters.pysauber neu erzeugen. - Tabellen (z. B. Änderungshistorie) werden weiterhin als Einzelzeilen extrahiert, nicht als RST-Tabelle rekonstruiert (wie im Konzept angekündigt).
Ausgangslage
- Reales Fortna-Rohmaterial liegt in
c:\10-Develop\projekte\Fortna\(zusätzliches Arbeitsverzeichnis dieser Session, nicht im Repo). Struktur wie indoc/Fortna.txtdokumentiert (00_CONTENTS_NOTES … 05_SUPPLIER_DOC), Versionsstände dort sind aktueller als indoc/Fortna.txt(z. B. Betriebsanleitung V2.4 statt V2.3, Wartungsanleitung V2.3, ILS V2.2, OMNIFLO V1.1, LoadingLoop V2.3).doc/Fortna.txt/doc/Fortna-size.txtsind nur noch als Struktur-Referenz zu verstehen, nicht als Quelle für den Extraktionslauf. chapters/(Base-Repo-Gerüst) existiert bereits vollständig mit.gitkeep-Platzhaltern gemäßdoc/kapitelstruktur.md.06_steuerung/loading_loop/wurde testweise mitconvert_to_rst.pyaus der LoadingLoop-Word-Datei befüllt (2 RST + 74 Bilder). Qualität ist noch unzureichend: Kopf-/Fußzeilen (Firmenadresse, Kontaktdaten) landen als normale Absätze im Fließtext, Tabellen (Änderungshistorie) werden zu einzelnen Zeilen ohne Tabellenstruktur zerlegt. Das ist ein bekanntes Problem der aktuellen_html_to_blocks-Logik inconvert_to_rst.pyund wird im Zuge dieser Arbeit mit adressiert (siehe Abschnitt "Bekannte Schwachstellen").- Vorhandene Skripte in
lib/(siehedoc/lib_skripte.md):convert_to_rst.py:.docx/Word-PDF → RST, erkennt Zielkapitel nur anhand Dateiname-Pattern im Root eines Ordners, kein Verständnis für den verschachtelten Fortna-Sprachordner-Baum.extract_products.py: Produktprogramm-PDFs → Bilder + RST (bereits fertig genutzt fürdata/Produktprogramm).jsonFromXlsx.py,extract_ids.py,project_from_xlsx.py: Stücklisten-Auswertung, für diese Aufgabe nicht direkt relevant.
- Kein Skript kennt bisher die komplette Fortna-Ordnerstruktur (Lieferantendoku-Baum, Layouts,
Schaltpläne, Prüfberichte) und keines erzeugt den projektspezifischen Ordner (
anlage.json,overrides/,images/) gemäßdoc/Kernkonzepte.md.
Entscheidungen (aus Rückfragen)
| Frage | Entscheidung |
|---|---|
| Lieferantendoku (~250 PDFs: SEW, Siemens, Leuze, Cognex, MiTek, Aventics, …) | Nur Verzeichnisliste, keine Kopie. RST-Referenztabelle mit Pfaden auf das Originalverzeichnis. |
| Sonstige PDFs (Zertifikate, Konfigurationsbeschreibung, Layouts, Schaltpläne, Notstopp/Bereichsstopp, Prüfberichte, Ersatzteilliste) | Gleiche Behandlung wie Lieferantendoku: nur Verzeichnisliste, keine Kopie nach chapters/. |
| Volltext-Konvertierung (Text + Bilder → RST) | Nur die 5 Hauptanleitungen: Betriebsanleitung, Wartungsanleitung, Funktionsbeschreibung ILS, Funktionsbeschreibung OMNIFLO, Funktionsbeschreibung LoadingLoop. |
| Projektordner-Ort | projekte/fortna/ innerhalb dieses Repos (docu_build), pragmatisch für jetzt; spätere Auslagerung in eigenes Repo bleibt möglich. |
| Sprachumfang | Nur Deutsch in diesem Durchlauf. Namenskonvention {name}.de.rst einhalten, EN/CZ als späterer zweiter Durchlauf vorgesehen. |
| Quelle | c:\10-Develop\projekte\Fortna\ (aktueller Stand), nicht doc/Fortna.txt. |
Umgang mit bestehendem chapters/06_steuerung/loading_loop/ |
Überschreiben/neu erzeugen – konsistent aus einem Guss statt Altbestand stehen lassen. |
Zielstruktur (Ergebnis nach Lauf)
chapters/
01_zertifikate/
konformitaetserklaerung/index.de.rst # Verzeichnisliste -> Originalpfade
konfigurationsbeschreibung/index.de.rst
02_sicherheit/ # unverändert (kein Fortna-Rohmaterial 1:1 zuordenbar)
03_anlagenbeschreibung/ # unverändert (Modul-Mechanismus, nicht Teil dieser Aufgabe)
04_betrieb/betriebsanleitung/
betriebsanleitung_500592_135776_v2_4.de.rst # Volltext + Bilder
images/img_001.png ...
05_wartung/wartungsanleitung/
wartungsanleitung_500592_v2_3.de.rst # Volltext + Bilder
images/...
06_steuerung/
ils/funktion_steuerung_ils_500592_v2_2.de.rst # Volltext + Bilder
omniflo/funktion_steuerung_omniflo_500592_v1_1.de.rst
loading_loop/funktion_steuerung_loadingloop_500592_v2_3.de.rst # neu erzeugt, ersetzt Altbestand
07_ersatzteile/index.de.rst # Verzeichnisliste -> Originalpfad SPARE_PARTS PDF
08_lieferantendoku/
antriebe/index.de.rst # Verzeichnisliste SEW, NORD, Leantechnik, DTS
elektrik/index.de.rst # Siemens, Leuze, Cognex, Werma, ...
pneumatik/index.de.rst # Aventics, ITS
stahlbau/index.de.rst # MiTek (As-Built, Statik, Zertifikate, ...)
sicherheitseinrichtungen/index.de.rst # ABS Sicherheitslinie
09_technische_unterlagen/
layouts/mechanisch/index.de.rst
layouts/elektrisch/index.de.rst
schaltplaene/index.de.rst
notstopp/index.de.rst
bereichsstopp/index.de.rst
10_anhang/
pruefberichte/index.de.rst
projekte/
fortna/
anlage.json # Projektmetadaten (Platzhalter/Vorschlag, manuell nachzuschärfen)
overrides/ # leer angelegt, Struktur gemäß Kernkonzepte.md
images/ # leer angelegt (projektspezifische Bilder, Kundenlogo etc.)
README.md # kurze Erläuterung was hier reinkommt
Jede index.de.rst-Verzeichnisliste enthält eine Tabelle: Dateiname, Hersteller/Kategorie
(aus Ordnername abgeleitet), Originalpfad (relativ zu einer konfigurierbaren Basis, z. B.
PV_FORTNA_SOURCE), Dateigröße. Kein PDF wird kopiert oder eingebettet – das hält den
Kapitelbaum schlank und vermeidet Redundanz zum Rohmaterial, das ohnehin an anderer Stelle
(Nextcloud/Projektordner) verwaltet wird.
Geplante Skripte (in lib/)
1. fortna_inventory.py (neu)
Scannt c:\10-Develop\projekte\Fortna\ rekursiv und baut ein Inventar (JSON) aller Dateien mit:
Pfad, Größe, erkannte Sprache (aus Ordnername: *_DE*/*_EN*/*_CZ*/*original* → de),
vermutetem Fortna-Kapitel (oberste zwei Ebenen) und vermutetem Ziel-Kapitel gemäß Mapping-Tabelle
aus doc/kapitelstruktur.md. Dient als Kontrollartefakt (results/fortna_inventory.json), auf
dessen Basis sich beide folgenden Skripte konfigurieren bzw. dessen Output sich manuell prüfen
lässt, bevor tatsächlich geschrieben wird (--dry-run Default, --apply zum Ausführen).
Grund für ein separates Inventarskript: 387 Dateien über 6 Top-Level-Ordner mit inkonsistenter
Sprachordner-Benennung (01_DE_original, 01_EN_original, 1_EN_original [Tippfehler im
Quellbaum], 02_CZ, 03_CZ_pro_celé_zařízení, …) – ein Trockenlauf mit Report ist nötig, um
Mapping-Lücken zu erkennen, bevor Dateien verschoben/verarbeitet werden.
2. fortna_convert_chapters.py (neu)
Nutzt das Inventar aus Schritt 1 (oder scannt bei Bedarf direkt) und führt zwei Aktionsarten aus:
- Volltext-Konvertierung für die 5 Hauptanleitungen: ruft die vorhandene Konvertierungslogik
aus
convert_to_rst.pywieder, aber mit expliziter Quelldatei-Liste (kein Verzeichnis-Scan) und fest zugeordnetem Zielkapitel (aus der Tabelle unten), statt der generischenCHAPTER_MAPPING-Heuristik. Überschreibt bestehende Ziel-RSTs/Bilder vollständig (Ordnerinhalt vorher leeren, dann neu schreiben). - Verzeichnislisten-Generierung für alle übrigen Kapitel (Zertifikate, Layouts, Schaltpläne,
Notstopp/Bereichsstopp, Prüfberichte, Ersatzteile, Lieferantendoku): läuft über die im
Inventar erkannten Dateien je Zielordner und rendert eine
index.de.rstmit RST-list-table (Dateiname, Pfad, Größe).
Fest zugeordnete Hauptanleitungen (Quelle → Ziel):
Quelldatei (DE, aktuellster Stand in projekte/Fortna) |
Zielkapitel |
|---|---|
02_INSTRUCTIONS.../01_DE_original/01_BETRIEBSANLEITUNG_500592_135776_V2.4.pdf |
04_betrieb/betriebsanleitung/ |
02_INSTRUCTIONS.../01_DE_original/02_WARTUNGSANLEITUNG_500592_V2.3.pdf |
05_wartung/wartungsanleitung/ |
02_INSTRUCTIONS.../01_DE_original/03_FUNKTION_STEUERUNG_ILS_500592_V2.2.pdf |
06_steuerung/ils/ |
02_INSTRUCTIONS.../01_DE_original/04_FUNKTION_STEUERUNG_OMNIFLO_500592_V1.1.pdf |
06_steuerung/omniflo/ |
02_INSTRUCTIONS.../01_DE_original/05_FUNKTION_STEUERUNG_LOADING_LOOP_500592_V2.3.pdf |
06_steuerung/loading_loop/ (ersetzt Altbestand) |
Alle fünf sind PDFs (keine .docx im Quellordner mehr vorhanden), daher wird der
is_word_pdf()-Pfad aus convert_to_rst.py verwendet (pdfminer-Textextraktion). Die extra
extract_products.py-Textheuristik (Schriftgrößen-basierte Überschriftenerkennung,
Kopf-/Fußzeilen-Ausschluss nach Y-Position) ist für Word-erstellte PDFs wie diese robuster als
die aktuelle convert_to_rst.py-Textheuristik (siehe Bekannte Schwachstellen) – Vorschlag: die
Extraktionsroutine aus extract_products.py (extract_text_to_rst, _is_noise,
extract_images) wiederverwenden/verallgemeinern statt der schwächeren pdfminer-Variante aus
convert_to_rst.py.
3. fortna_init_project.py (neu)
Legt projekte/fortna/ an: anlage.json (Platzhalter mit Projektnummer 500592/KA135776,
Sprache ["de"], normen_region offen als TODO), leere overrides/- und images/-Ordner mit
.gitkeep, sowie ein kurzes README.md. Einmaliger Lauf, kein Datei-Scan nötig – im
Wesentlichen ein Gerüst-Generator.
Bekannte Schwachstellen der bisherigen Konvertierung (zu beheben)
Der Altbestand in chapters/06_steuerung/loading_loop/ zeigt zwei konkrete Probleme der
aktuellen convert_to_rst.py-Logik, die für die 5 Hauptanleitungen behoben werden sollten:
- Kopf-/Fußzeilen als Fließtext: Firmenadresse, Kontaktdaten, Projektnummer erscheinen als
normale Absätze mitten im Dokument (weil
pdfminer.high_level.extract_textkeine Positionsinformation liefert, mit der man Kopf-/Fußzeilen herausfiltern könnte).extract_products.pylöst das bereits überpage.get_text("dict")mit Y-Positions-Filter (bbox[1] < 100/bbox[3] > page_height - 50) – diese Technik übernehmen. - Tabellen zerfallen in Einzelzeilen: Die Änderungshistorie-Tabelle wird zu einer Folge
einzelner Absätze ohne Tabellenstruktur. Vorschlag für ersten Wurf: Tabellen nicht als
RST-Table rekonstruieren (zu fehleranfällig aus PDF-Text), sondern als eingerückten
.. code-block::oder einfache Aufzählung kennzeichnen, mit.. todo:: Tabelle manuell nachbearbeiten-Marker – ehrlich statt falsch-schön.
Offene Punkte / Annahmen, die ich getroffen habe
- Ich gehe davon aus, dass
PV_FORTNA_SOURCE(oder ein--source-dir-Argument) als neue Umgebungsvariable/Parameter eingeführt wird, die aufc:\10-Develop\projekte\Fortna\zeigt, da dieser Pfad außerhalb des Repos liegt und nicht überPV_DATA/PV_EXAMPLESerreichbar ist. 02_sicherheit/und03_anlagenbeschreibung/bleiben in diesem Durchlauf unangetastet – es gibt keine 1:1-Quelle dafür inprojekte/Fortna/(Risikobewertung liegt als separate.docx-Dateien direkt im Repo-Root vonchapters/, siehe Git-Status, nicht Teil dieser Aufgabe).- Die generierten
index.de.rst-Verzeichnislisten verweisen auf absolute oder repo-relative-konfigurierbare Pfade zum Rohmaterial – das bedeutet, das Zielsystem (Sphinx) bekommt keine eigenständig lauffähige Doku ohne Zugriff aufprojekte/Fortna/. Das ist so gewollt gemäß der Entscheidung "nur Verzeichnisliste", sollte aber vor dem produktiven PDF-Build nochmal bewusst bestätigt werden (spätestens beim erstensphinx-build-Versuch fehlen dann die Downloads/Links).
Nächste Schritte
- Dieses Konzept abstimmen (insb. Umgang mit
02_sicherheit/Risikobewertung-Docx im Root vonchapters/, sowie die Pfad-Referenzierung in den Verzeichnislisten). fortna_inventory.pyimplementieren und Trockenlauf-Report gegenprojekte/Fortna/prüfen.fortna_convert_chapters.pyimplementieren (inkl. Wiederverwendung derextract_products.py-Textextraktion), auf 5 Hauptanleitungen anwenden, Ergebnis stichprobenhaft gegenlesen.fortna_init_project.pyimplementieren,projekte/fortna/anlegen.bin/-Wrapper-Skripte (.bat/.sh) für alle drei ergänzen, analog bestehender Konvention.