Neues Konzept: Eine PDF Datei pro Lerngruppe

This commit is contained in:
2026-04-19 12:37:42 +02:00
parent 6c4e7120dc
commit 79ec1acf94
32 changed files with 2646 additions and 47283 deletions

View File

@@ -8,7 +8,7 @@ Beim vorliegenden Projekt handelt es sich um ein Python-Skript, das für beliebi
- CSV-Dateien mit einer Namensliste für jede Lerngruppe und - CSV-Dateien mit einer Namensliste für jede Lerngruppe und
- der Konfiguration der gewünschten Ausgabe für jede Lerngruppe - der Konfiguration der gewünschten Ausgabe für jede Lerngruppe
eine gemeinsame PDF-Datei generiert, die für jede Lerngruppe jeweils eine PDF-Datei generiert, die
- eine (Noten)-Übersicht für die Lerngruppe, - eine (Noten)-Übersicht für die Lerngruppe,
- für jede Lernerfolgskontrolle eine Punkte- und Notentabelle, - für jede Lernerfolgskontrolle eine Punkte- und Notentabelle,
@@ -18,44 +18,34 @@ eine gemeinsame PDF-Datei generiert, die für jede Lerngruppe
- eine Geburtstagsliste und - eine Geburtstagsliste und
- ein Blatt zur Planung des Halbjahres - ein Blatt zur Planung des Halbjahres
für ein Halbjahr umfasst. Zusätzlich kann optional als Startseite ein Stundenplan eingebunden werden. für ein Halbjahr umfasst.
Diese PDF-Datei kann anschließend mit einem Tablet und einem Eingabestift mit Inhalt gefüllt werden. Alle Bestandteile sind untereinander verlinkt, so dass sehr einfach zwischen der Bearbeitung der diversen Tabellen der Lerngruppe sowie zwischen den Lerngruppen gewechselt werden kann. Diese PDF-Dateien können anschließend mit einem Tablet und einem Eingabestift mit Inhalt gefüllt werden. Alle Bestandteile sind untereinander verlinkt, so dass sehr einfach zwischen der Bearbeitung der diversen Tabellen der Lerngruppe gewechselt werden kann.
### Unterstützte Geräte ### Unterstützte Geräte
Die PDF-Ausgabe ist für die folgenden Tablet Geräte optimiert worden. Verlinkt ist zur Illustration für jedes Gerät eine aus (fiktiven) Beispieldaten erzeugte PDF-Ausgabe.
#### a) reMarkable #### a) reMarkable
Für alle drei aktuellen reMarkable Tablets werden PDF Dokumente generiert, die exakt der Bildschirmgröße entsprechen. Damit entfällt das Zoomen bei der Bearbeitung. Für alle drei aktuellen reMarkable Tablets werden PDF Dokumente generiert, die exakt der Bildschirmgröße entsprechen. Damit entfällt das Zoomen bei der Bearbeitung.
Alle drei Geräte blenden am linken oder rechten Bildschirmrand bei der Bearbeitung eines Dokuments eine Toolbar mit den gängigen Bearbeitungswerkzeugen ein. Diese Toolbar verdeckt dann aber einen Teil des Dokuments. Als Option kann deshalb ein linker oder rechter Rand für die Toolbar freigelassen werden. Alle drei Geräte blenden am linken oder rechten Bildschirmrand bei der Bearbeitung eines Dokuments eine Toolbar mit den gängigen Bearbeitungswerkzeugen ein. Diese Toolbar verdeckt dann aber einen Teil des Dokuments. Als Option kann deshalb ein linker oder rechter Rand für die Toolbar freigelassen werden.
Bei den beiden großen Geräten rm2 und Paper Pro ist in den folgenden Beispieldokumenten ein Rand gelassen worden, beim kompakten Gerät Paper Pro Move nicht. Beispielausgaben für das reMarkable PaperPro:
- [reMarkable 2](./src/data/rm2.pdf) - [klasse-5a.pdf](./src/data/klasse-5a.pdf)
- [reMarkable Paper Pro](./src/data/paperpro.pdf) - [klasse-6b.pdf](./src/data/klasse-6b.pdf)
- [reMarkable Paper Pro Move](./src/data/move.pdf) - [kurs-if-9.pdf](./src/data/kurs-if-9.pdf)
- [kurs-if-ef.pdf](./src/data/kurs-if-ef.pdf)
#### b) Apple iPad #### b) Apple iPad
Für alle aktuellen iPads werden PDF Dokumente erzeugt, die der Bildschirmgröße entsprechen. Da zur Bearbeitung eine App verwendet wird (z.B. die eingebaute Vorschau App oder eine der vielen angebotenen PDF Editor Apps), hängt der Komfort bei der Bearbeitung dieser Vollbilddokumente sehr von der jeweiligen App ab. Da auch die Menüführung in jeder App anders aufgebaut ist, wird hier auf die Option eines Rands verzichtet. Für alle aktuellen iPads werden PDF Dokumente erzeugt, die der Bildschirmgröße entsprechen. Da zur Bearbeitung eine App verwendet wird (z.B. die eingebaute Vorschau App oder eine der vielen angebotenen PDF Editor Apps), hängt der Komfort bei der Bearbeitung dieser Vollbilddokumente sehr von der jeweiligen App ab. Da auch die Menüführung in jeder App anders aufgebaut ist, wird hier auf die Option eines Rands verzichtet.
- iPad [7.-9.](./src/data/ipad789.pdf) und [10.-11.](./src/data/ipad1011.pdf) Gen.
- iPad Mini [2.-5.](./src/data/mini2345.pdf) und [6.-7.](./src/data/mini67.pdf) Gen.
- iPad Air 11 Zoll [4.-7.](./src/data/air4567.pdf) Gen.
- iPad Air 13 Zoll [7.](./src/data/air13-7.pdf) Gen.
- iPad Pro 11 Zoll [2.-4.](./src/data/pro234.pdf) Gen. und [5.-6.](./src/data/pro56.pdf) Gen.
- iPad Pro 13 Zoll [3.-6.](./src/data/pro13-3456.pdf) Gen. und [7.-8.](./src/data/pro13-78.pdf) Gen.
#### c) andere Geräte #### c) andere Geräte
Für alle übrigen Geräte stehen Ausgaben in den Formaten DIN A6, A5 und A4 zur Verfügung. Sie müssen dann auf dem jeweiligen Gerät passend skaliert werden. Vorteil von A6, A5 und A4 ist der einfache Ausdruck. Für alle übrigen Geräte stehen Ausgaben in den Formaten DIN A6, A5 und A4 zur Verfügung. Sie müssen dann auf dem jeweiligen Gerät passend skaliert werden. Vorteil von A6, A5 und A4 ist der einfache Ausdruck.
- [DIN A6](src/data/a6.pdf) und [DIN A5](src/data/a5.pdf) und [DIN A4](src/data/a4.pdf)
### Dokumentation der Verarbeitung ### Dokumentation der Verarbeitung

View File

@@ -16,9 +16,6 @@ kw_start = 35
kw_ende = 6 kw_ende = 6
kw_ferien = 42,43,52,1 kw_ferien = 42,43,52,1
# Startseite: Binde den Stundenplan aus der angegebenen Datei ein (leer: kein Stundenplan)
stundenplandatei = stundenplan.md
# Trenner der Spalten in den CSV-Eingabedateien # Trenner der Spalten in den CSV-Eingabedateien
csvtrenner = ; csvtrenner = ;
@@ -41,7 +38,6 @@ Die Parameter sind zwar selbsterklärend, werden hier aber dennoch einmal kurz e
- Für das Halbjahr ist eine 1 oder 2 einzutragen. - Für das Halbjahr ist eine 1 oder 2 einzutragen.
- Für die Übersichtsseite des Habjahrs sind die Kalenderwoche des Beginns und die Kalenderwoche des Endes anzugeben. (Es liegt in der Natur der Sache, dass die beiden Zahlen nicht aufsteigend sein müssen, wenn ein Halbjahr zwei Kalenderjahre umfasst. Das Skript berücksichtigt dies automatisch.) - Für die Übersichtsseite des Habjahrs sind die Kalenderwoche des Beginns und die Kalenderwoche des Endes anzugeben. (Es liegt in der Natur der Sache, dass die beiden Zahlen nicht aufsteigend sein müssen, wenn ein Halbjahr zwei Kalenderjahre umfasst. Das Skript berücksichtigt dies automatisch.)
- Auf Wunsch können die Ferienwochen aus der Übersicht entfernt werden. Die entsprechenden Kalenderwochen müssen hier (nur mit Komma und ohne Leerzeichen getrennt) angegeben werden. - Auf Wunsch können die Ferienwochen aus der Übersicht entfernt werden. Die entsprechenden Kalenderwochen müssen hier (nur mit Komma und ohne Leerzeichen getrennt) angegeben werden.
- Soll die Startseite des Zieldokuments einen Stundenplan enthalten, so ist dieser im Eingabeverzeichnis als Markdown Dokument anzugeben (vgl. auch nächster Abschnitt). Der Dateiname wird hier festgelegt. Fehlt der Dateiname, so wird der Stundenplan automatisch weggelassen.
- Für die CSV Dateien kann hier das Symbol zum Trennen der Spalte (voreingestellt Semikolon) bei Bedarf angepasst werden. - Für die CSV Dateien kann hier das Symbol zum Trennen der Spalte (voreingestellt Semikolon) bei Bedarf angepasst werden.
- Auf allen ReMarkable Zieldevices wird bei der Bearbeitung eines Dokuments eine Toolbar eingeblendet. Um Platz für diese Toolbar zu schaffen, kann links oder rechts ein kleiner Rand gelassen werden. - Auf allen ReMarkable Zieldevices wird bei der Bearbeitung eines Dokuments eine Toolbar eingeblendet. Um Platz für diese Toolbar zu schaffen, kann links oder rechts ein kleiner Rand gelassen werden.
- Zum Schluss kommt die wichtigste Festlegung, das Zielgerät. Hier kann zwischen den aufgelisteten Geräten gewählt werden. - Zum Schluss kommt die wichtigste Festlegung, das Zielgerät. Hier kann zwischen den aufgelisteten Geräten gewählt werden.

View File

@@ -29,16 +29,14 @@ Auf der Konsole werden die Verarbeitungsschritte dokumentiert und auch evtl. Feh
``` ```
Verarbeite das Verzeichnis: data/ Verarbeite das Verzeichnis: data/
Verarbeite Datei: data/klasse-5a.csv - Erzeuge PDF-Datei: klasse-5a.pdf
Verarbeite Datei: data/klasse-6b.csv - Erzeuge PDF-Datei: klasse-6b.pdf
Verarbeite Datei: data/kurs-if-9.csv - Erzeuge PDF-Datei: kurs-if-9.pdf
Verarbeite Datei: data/kurs-if-ef.csv - Erzeuge PDF-Datei: kurs-if-ef.pdf
Erzeuge PDF-Datei: rm2.pdf
Fertig! Fertig!
``` ```
Die Ausgabedatei, dessen Namen das Zielgerät angibt (im obigen Beispiel ``rm2.pdf`` Die Ausgabedateien werden dabei im Verzeichnis der Eingabedateien abgelegt.
für das Ziel Gerät reMarkable 2), wird dabei im Verzeichnis der Eingabedateien abgelegt.
### Option: Angabe des Eingabeverzeichnisses ### Option: Angabe des Eingabeverzeichnisses

View File

@@ -16,7 +16,7 @@ Treffen beide Möglichkeiten zu, so hat die erste Vorrang. Trifft keine der beid
### 2. Konfiguration der PDF-Ausgabe ### 2. Konfiguration der PDF-Ausgabe
Für die Erzeugung der PDF-Ausgabe ist pro Lerngruppe eine CSV-Datei mit den Namen der SchülerInnen erforderlich. Zusätzlich können für jede Lerngruppe diverse Parameter zur Darstellung der Ausgabe konfiguriert werden. Einige allgemeine Parameter wie das aktuelle Halbjahr gelten dabei für alle Lerngruppen. Der optionale Stundenplan wird auf der Startseite dargestellt. Für die Erzeugung der PDF-Ausgabe ist pro Lerngruppe eine CSV-Datei mit den Namen der SchülerInnen erforderlich. Zusätzlich können für jede Lerngruppe diverse Parameter zur Darstellung der Ausgabe konfiguriert werden. Einige allgemeine Parameter wie das aktuelle Halbjahr gelten dabei für alle Lerngruppen.
- [CSV-Datei für jede Lerngruppe](csv.md) - [CSV-Datei für jede Lerngruppe](csv.md)
@@ -24,5 +24,3 @@ Für die Erzeugung der PDF-Ausgabe ist pro Lerngruppe eine CSV-Datei mit den Nam
- [allgemeiner Teil](allgemein.md) - [allgemeiner Teil](allgemein.md)
- [Teil für jede Lerngruppe](lerngruppe.md) - [Teil für jede Lerngruppe](lerngruppe.md)
- [Stundenplan-Datei](stundenplan.md)

View File

@@ -8,10 +8,7 @@ In der Datei ``input.ini`` im Eingabeverzeichnis wird für neben einigen allgeme
# Bezeichnung der Lerngruppe # Bezeichnung der Lerngruppe
bezeichnung = Mathe 5a bezeichnung = Mathe 5a
# Kurzbezeichnung der Lerngruppe # Abkürzende Bezeichnung der Lerngruppe (für Navileiste auf kleinen Geräten)
kurzbezeichnung = Mathe 5a
# Abkürzende Bezeichnung der Lerngruppe (für Stundenplan und Navileiste auf kleinen Geräten)
abkuerzung = M 5a abkuerzung = M 5a
# Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren) # Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren)
@@ -42,7 +39,6 @@ checkliste_seiten = 2
Die Parameter sind zwar selbsterklärend, werden hier aber dennoch einmal kurz erläutert: Die Parameter sind zwar selbsterklärend, werden hier aber dennoch einmal kurz erläutert:
- Die Bezeichnung der Lerngruppe wird als Überschrift überall dort verwendet, wo genügend Platz zur Verfügung steht. - Die Bezeichnung der Lerngruppe wird als Überschrift überall dort verwendet, wo genügend Platz zur Verfügung steht.
- Ist nur wenig Platz vorhanden (z.B. im Stundenplan), kommt die Kurzbeschreibung der Lerngruppe zum Einsatz.
- Auf kleinen Devices wird entsprechend die abkürzende Schreibweise verwendet. - Auf kleinen Devices wird entsprechend die abkürzende Schreibweise verwendet.
- Die Anzahl der schriftlichen Lernerfolgskontrollen gibt an, wie viele Korrekturbögen erzeugt werden. Die Anzahl 0 sorgt dafür, dass diese automatisch weggelassen werden. - Die Anzahl der schriftlichen Lernerfolgskontrollen gibt an, wie viele Korrekturbögen erzeugt werden. Die Anzahl 0 sorgt dafür, dass diese automatisch weggelassen werden.
- Die Bezeichnung der Lernerfolgskontrolle passt sich dem Sprachgebrauch an, z.B. Arbeit oder Kursarbeit oder Klausur. - Die Bezeichnung der Lernerfolgskontrolle passt sich dem Sprachgebrauch an, z.B. Arbeit oder Kursarbeit oder Klausur.

View File

@@ -1,26 +0,0 @@
# Stundenplan
Wird ein Stundenplan auf der Startseite gewünscht, so wird die im allgemeinen Teil der Ausgabekonfiguration angegebene Markdown-Datei eingelesen und aufbereitet.
Die Beispieldatei ``stundenplan.md`` kann dabei als Ausgangspunkt verwendet werden:
```md
| St. | Montag | Dienstag | Mittwoch | Donnerstag | Freitag |
| :------: | :----------: | :----------: | :----------: | :----------: | :----------: |
| 1.<br>2. | [klasse-5a] | | | [klasse-5a] | [klasse-6b] |
| 3.<br>4. | [klasse-6b] | [kurs-if-ef] | [klasse-5a] | [klasse-6b] | |
| 5.<br>6. | [kurs-if-9] | [[VERT]] | [kurs-if-ef] | | |
| 7. | | | | | |
| 8.<br>9. | | [kurs-if-9] | | | |
```
Dabei ist zu beachten:
- Durch ``<br>`` kann ein Zeilenumbruch in einer Zelle erzwungen werden kann.
- Die Spalten der Tabelle werden durch ``|`` voneinander abgetrennt.
- Wird die ID einer Lerngruppe in eckige Klammern gesetzt (z.B. ``[klasse-5a]``), so wird die Aufbereitung automatisch einen Verweis auf die Seite generieren, auf der die Informationen zur zugehörigen Lerngruppe beginnen. Der Verweis wird als Box mit dem passenden farbigem Hintergrund bzw. auf SW-Geräten mit leichter Schattierung formatiert.
- Gibt es Einträge ohne Lerngruppe (z.B. für Vertretungsbereitschaft o.ä.), so wird eine Box auch dann erzeugt, wenn der Text in doppelte eckige Klammern gesetzt wird. Beispiel: `[[VERT]]`
- Die Aufteilung der sechs Spalten (Stunde, Montag, ...) sollte beibehalten werden. Bei der Aufbereitung wird die erste Spalte enger dargestellt, alle übrigen Spalten werden gleich breit formatiert.
Fehlt die Datei für den Stundenplan (bewusst oder versehentlich), so wird automatisch auf die Berücksichtigung eines Stundenplans auf der Startseite verzichtet.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -35,10 +35,7 @@ device = paperpro
# Bezeichnung der Lerngruppe # Bezeichnung der Lerngruppe
bezeichnung = Mathe 5a bezeichnung = Mathe 5a
# Kurzbezeichnung der Lerngruppe (für Stundenplan) # Abkürzende Bezeichnung der Lerngruppe (für Navileiste auf kleinen Geräten)
kurzbezeichnung = Mathe 5a
# Abkürzende Bezeichnung der Lerngruppe (für Stundenplan und Navileiste auf kleinen Geräten)
abkuerzung = M 5a abkuerzung = M 5a
# Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren) # Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren)
@@ -71,10 +68,7 @@ checkliste_seiten = 2
# Bezeichnung der Lerngruppe # Bezeichnung der Lerngruppe
bezeichnung = Mathe 6b bezeichnung = Mathe 6b
# Kurzbezeichnung der Lerngruppe (für Stundenplan) # Abkürzende Bezeichnung der Lerngruppe (für Navileiste auf kleinen Geräten)
kurzbezeichnung = Mathe 6b
# Abkürzende Bezeichnung der Lerngruppe (für Stundenplan und Navileiste auf kleinen Geräten)
abkuerzung = M 6b abkuerzung = M 6b
# Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren) # Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren)
@@ -107,10 +101,7 @@ checkliste_seiten = 2
# Bezeichnung der Lerngruppe # Bezeichnung der Lerngruppe
bezeichnung = Informatik 9 bezeichnung = Informatik 9
# Kurzbezeichnung der Lerngruppe (für Stundenplan) # Abkürzende Bezeichnung der Lerngruppe (für Navileiste auf kleinen Geräten)
kurzbezeichnung = Info 9
# Abkürzende Bezeichnung der Lerngruppe (für Stundenplan und Navileiste auf kleinen Geräten)
abkuerzung = If 9 abkuerzung = If 9
# Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren) # Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren)
@@ -143,10 +134,7 @@ checkliste_seiten = 2
# Bezeichnung der Lerngruppe # Bezeichnung der Lerngruppe
bezeichnung = Informatik EF bezeichnung = Informatik EF
# Kurzbezeichnung der Lerngruppe (für Stundenplan) # Abkürzende Bezeichnung der Lerngruppe (für Navileiste auf kleinen Geräten)
kurzbezeichnung = Info EF
# Abkürzende Bezeichnung der Lerngruppe (für Stundenplan und Navileiste auf kleinen Geräten)
abkuerzung = If EF abkuerzung = If EF
# Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren) # Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

755
src/data/klasse-5a.pdf Normal file

File diff suppressed because one or more lines are too long

736
src/data/klasse-6b.pdf Normal file

File diff suppressed because one or more lines are too long

490
src/data/kurs-if-9.pdf Normal file

File diff suppressed because one or more lines are too long

603
src/data/kurs-if-ef.pdf Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,8 +0,0 @@
| St. | Montag | Dienstag | Mittwoch | Donnerstag | Freitag |
| :------: | :----------: | :----------: | :----------: | :----------: | :----------: |
| 1.<br>2. | [klasse-5a] | | | [klasse-5a] | [klasse-6b] |
| 3.<br>4. | [klasse-6b] | [kurs-if-ef] | [klasse-5a] | [klasse-6b] | |
| 5.<br>6. | [kurs-if-9] | [[VERT]] | [kurs-if-ef] | | |
| 7. | | | | | |
| 8.<br>9. | | [kurs-if-9] | | | |

View File

@@ -7,7 +7,7 @@ from configparser import ConfigParser
from xhtml2pdf import pisa from xhtml2pdf import pisa
sys.path.append(os.path.abspath("./pages")) sys.path.append(os.path.abspath("./pages"))
import start, halbjahr, birthday, uebersicht, korrektur, somi, ha, checkliste import halbjahr, birthday, uebersicht, korrektur, somi, ha, checkliste
# 1. Eingabeverzeichnis bestimmen # 1. Eingabeverzeichnis bestimmen
@@ -154,26 +154,22 @@ except KeyError:
exit(0) exit(0)
# 5. Baue die Ausgabe aus den einzelnen Bestandteilen zusammen # 5. Verarbeite nacheinander alle Eingabedateien = Lerngruppen
body = ''
# Startseite einbinden
body = body + start.erstelleStartseite(lerngruppen, path, config, inputs)
# Verarbeite nacheinander alle Eingabedateien = Lerngruppen
for datei in dateien: for datei in dateien:
print(" - Verarbeite Datei: "+datei) body = ''
if (not(os.path.exists(datei))): if (not(os.path.exists(datei))):
print("Datei "+datei+" nicht vorhanden!") print("Datei "+datei+" nicht vorhanden!")
exit(0) exit(0)
# Implizite Konfiguration der aktuellen Lerngruppe aus Benutzerconfig auslesen # a) Implizite Konfiguration der aktuellen Lerngruppe aus Benutzerconfig auslesen
dateiname = datei.replace(path,"") dateiname = datei.replace(path,"")
kursid = dateiname.replace(".csv","") kursid = dateiname.replace(".csv","")
print(" - Erzeuge PDF-Datei: " + kursid + '.pdf')
try: try:
kurs_inputs = inputs[kursid] kurs_inputs = inputs[kursid]
except KeyError: except KeyError:
@@ -186,7 +182,7 @@ for datei in dateien:
print('Der Schlüssel "bezeichnung" fehlt im Bereich "'+kursid+'" der Input-Datei!') print('Der Schlüssel "bezeichnung" fehlt im Bereich "'+kursid+'" der Input-Datei!')
exit(0) exit(0)
# CSV Datei mit Schülernamen einlesen und aufbereiten # b) CSV Datei mit Schülernamen einlesen und aufbereiten
csvdaten = open(datei, encoding="utf8") csvdaten = open(datei, encoding="utf8")
csvdatenReader = csv.reader(csvdaten, delimiter=csv_trenner) csvdatenReader = csv.reader(csvdaten, delimiter=csv_trenner)
@@ -219,14 +215,14 @@ for datei in dateien:
gebdatum = row[2] gebdatum = row[2]
gebdaten.append(gebdatum) gebdaten.append(gebdatum)
except IndexError: except IndexError:
print(' - Einträge für Geburtstag fehlen für Lerngruppe "'+kursid+'"!') print(' - Geburtstage fehlen für die Lerngruppe.')
gebdaten = [] gebdaten = []
gebdaten_all = False gebdaten_all = False
# Übersichtsseite Noten zusammenbauen # c) Übersichtsseite Noten zusammenbauen
body = body + uebersicht.erstelleUebersicht(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs) body = body + uebersicht.erstelleUebersicht(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# optional: Korrekturbögen zusammenbauen # d) optional: Korrekturbögen zusammenbauen
try: try:
schr_anzahl = int(kurs_inputs["schriftlich_anzahl"]) schr_anzahl = int(kurs_inputs["schriftlich_anzahl"])
except KeyError: except KeyError:
@@ -235,10 +231,10 @@ for datei in dateien:
if (schr_anzahl>0): if (schr_anzahl>0):
body = body + korrektur.erstelleKorrekturbogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs) body = body + korrektur.erstelleKorrekturbogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# SoMi-Bogen zusammenbauen # e) SoMi-Bogen zusammenbauen
body = body + somi.erstelleSoMiBogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs) body = body + somi.erstelleSoMiBogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# optional: HA-Bogen zusammenbauen # f) optional: HA-Bogen zusammenbauen
try: try:
ha_zeilen = int(kurs_inputs["ha_zeilen"]) ha_zeilen = int(kurs_inputs["ha_zeilen"])
except KeyError: except KeyError:
@@ -247,31 +243,28 @@ for datei in dateien:
if (ha_zeilen>0): if (ha_zeilen>0):
body = body + ha.erstelleHABogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs) body = body + ha.erstelleHABogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# Checkliste(n) zusammenbauen # g) Checkliste(n) zusammenbauen
body = body + checkliste.erstelleCheckliste(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs) body = body + checkliste.erstelleCheckliste(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# Geburtstagsseite zusammenbauen # h) Geburtstagsseite zusammenbauen
if (len(gebdaten)==0): if (len(gebdaten)>0):
print(' - Geburtstagsliste wird weggelassen.')
else:
if (namen_kurzlang=="lang"): if (namen_kurzlang=="lang"):
body = body + birthday.erstelleGeburtstagsBogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs) body = body + birthday.erstelleGeburtstagsBogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
else: else:
body = body + birthday.erstelleGeburtstagsBogen(kursid, klassekurs_name, lerngruppen, path, namen2, gebdaten, config, inputs, kurs_inputs) body = body + birthday.erstelleGeburtstagsBogen(kursid, klassekurs_name, lerngruppen, path, namen2, gebdaten, config, inputs, kurs_inputs)
# Planungsseite für das Halbjahr zusammenbauen # i) Planungsseite für das Halbjahr zusammenbauen
body = body + halbjahr.erstelleHalbjahresuebersicht(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs) body = body + halbjahr.erstelleHalbjahresuebersicht(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# 6. Abschluss: PDF Generierung # j) PDF Generierung
html_source = '<html><head>' html_source = '<html><head>'
html_source += '<link rel="stylesheet" href="'+css_devicefile+'">' html_source += '<link rel="stylesheet" href="'+css_devicefile+'">'
html_source += '</head><body>'+body+'</body></html>' html_source += '</head><body>'+body+'</body></html>'
pisa.showLogging() pisa.showLogging()
datei_ausgabe = path + device + '.pdf' datei_ausgabe = path + kursid + '.pdf'
print("Erzeuge PDF-Datei: " + device + '.pdf')
with open(datei_ausgabe, "w+b") as result_file: with open(datei_ausgabe, "w+b") as result_file:
@@ -285,4 +278,5 @@ with open(datei_ausgabe, "w+b") as result_file:
if pisa_status.err: if pisa_status.err:
print("Fehler bei der Erzeugung der PDF aus HTML!") print("Fehler bei der Erzeugung der PDF aus HTML!")
print("Fertig!") print("Fertig!")

View File

@@ -1,55 +1,6 @@
import os import os
def erstelleHauptnavigation(lerngruppen, path, config, inputs):
try:
rand = inputs["Allgemein"]["rand"]
except KeyError:
print('Der Schlüssel Allgemein oder "rand" existiert nicht in der Input-Datei!')
exit(0)
if (rand=="rechts"):
navi = "&nbsp;&nbsp;&nbsp;" # Platz für Schließen-Symbol schaffen
else:
navi = ""
count = 0
for kursid in lerngruppen:
count = count + 1
try:
kurs_inputs_aktuell = inputs[kursid]
except KeyError:
print('Der Bereichsschlüssel "'+kursid+'" (zur entsprechenden Datei) existiert nicht in der Input-Datei (3).')
exit(0)
try:
bezeichnung = config["Navigation"]["bezeichnung"]
except KeyError:
print('Der Schlüssel Navigation oder "kurzbezeichnung" existiert nicht in der Device-Datei!')
exit(0)
try:
klassekurs_aktuell = kurs_inputs_aktuell["bezeichnung"]
if (bezeichnung=='kurz'):
klassekurs_print = kurs_inputs_aktuell["kurzbezeichnung"]
elif (bezeichnung=='abgekuerzt'):
klassekurs_print = kurs_inputs_aktuell["abkuerzung"]
else:
klassekurs_print = kurs_inputs_aktuell["bezeichnung"]
except KeyError:
print('Der Schlüssel "bezeichnung" o.ä. fehlt im Bereich "'+kursid+'" der Input-Datei!')
exit(0)
myclass = ' n'+str(count) # Navileisten-CSS nX
navi += '<span class="hn-part"><a href="#'+klassekurs_aktuell+'">&nbsp;<img class="icon" src="img/user-multiple-4.svg"/><span class="'+myclass+'">'+klassekurs_print+'</span></a>&nbsp;</span>'
navileiste = '<p class="hn">'+navi+'</p>'
return navileiste
def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, lerngruppen, path, config, inputs, kurs_inputs): def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, lerngruppen, path, config, inputs, kurs_inputs):
@@ -72,15 +23,9 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
try: try:
bezeichnung = config["Navigation"]["bezeichnung"] bezeichnung = config["Navigation"]["bezeichnung"]
except KeyError: except KeyError:
print('Der Schlüssel Navigation oder "kurzbezeichnung" existiert nicht in der Device-Datei!') print('Der Schlüssel Navigation oder "bezeichnung" existiert nicht in der Device-Datei!')
exit(0) exit(0)
# Link zur Startseite
if (bezeichnung=='abgekuerzt'):
navi += '<span class="kn-part"><a href="#Home">&nbsp;<img class="icon" src="img/chevron-up-circle.svg"/></a></span>&nbsp;&nbsp;&nbsp;&nbsp;'
else:
navi += '<span class="kn-part"><a href="#Home">&nbsp;<img class="icon" src="img/chevron-up-circle.svg"/>zurück</a></span>&nbsp;&nbsp;&nbsp;&nbsp;'
# Notenübersicht # Notenübersicht
if (bezeichnung=='abgekuerzt'): if (bezeichnung=='abgekuerzt'):
if (current=='übersicht'): if (current=='übersicht'):
@@ -89,9 +34,9 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Overview">&nbsp;<img class="icon" src="img/user-multiple-4.svg"/></a>&nbsp;</span>' navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Overview">&nbsp;<img class="icon" src="img/user-multiple-4.svg"/></a>&nbsp;</span>'
else: else:
if (current=='übersicht'): if (current=='übersicht'):
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/user-multiple-4-current.svg"/><span class="kn-current">Übersicht</span></span>' navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/user-multiple-4-current.svg"/><span class="kn-current">Start</span></span>'
else: else:
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Overview">&nbsp;<img class="icon" src="img/user-multiple-4.svg"/>Übersicht</a></span>' navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Overview">&nbsp;<img class="icon" src="img/user-multiple-4.svg"/>Start</a></span>'
# Arbeiten/Klausuren # Arbeiten/Klausuren
schr_anzahl = int(kurs_inputs["schriftlich_anzahl"]) schr_anzahl = int(kurs_inputs["schriftlich_anzahl"])
@@ -141,9 +86,9 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'HA">&nbsp;<img class="icon" src="img/home-2.svg"/></a>&nbsp;</span>' navi += '<span class="kn-part"><a href="#'+klassekurs_name+'HA">&nbsp;<img class="icon" src="img/home-2.svg"/></a>&nbsp;</span>'
else: else:
if (current=='ha'): if (current=='ha'):
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/home-2-current.svg"/><span class="kn-current">Haus</span></span>' navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/home-2-current.svg"/><span class="kn-current">Hausaufgaben</span></span>'
else: else:
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'HA">&nbsp;<img class="icon" src="img/home-2.svg"/>Haus</a></span>' navi += '<span class="kn-part"><a href="#'+klassekurs_name+'HA">&nbsp;<img class="icon" src="img/home-2.svg"/>Hausaufgaben</a></span>'
# Checklisten # Checklisten
if (bezeichnung=='abgekuerzt'): if (bezeichnung=='abgekuerzt'):
@@ -153,9 +98,9 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Check">&nbsp;<img class="icon" src="img/check-square-2.svg"/></a>&nbsp;</span>' navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Check">&nbsp;<img class="icon" src="img/check-square-2.svg"/></a>&nbsp;</span>'
else: else:
if (current=='check'): if (current=='check'):
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/check-square-2-current.svg"/><span class="kn-current">Check</span></span>' navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/check-square-2-current.svg"/><span class="kn-current">Checklisten</span></span>'
else: else:
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Check">&nbsp;<img class="icon" src="img/check-square-2.svg"/>Check</a></span>' navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Check">&nbsp;<img class="icon" src="img/check-square-2.svg"/>Checklisten</a></span>'
# Geburtstagsseite # Geburtstagsseite
if (len(gebdaten)>0): if (len(gebdaten)>0):
@@ -166,9 +111,9 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Birthday">&nbsp;<img class="icon" src="img/balloons.svg"/></a>&nbsp;</span>' navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Birthday">&nbsp;<img class="icon" src="img/balloons.svg"/></a>&nbsp;</span>'
else: else:
if (current=='gebtag'): if (current=='gebtag'):
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/balloons-current.svg"/><span class="kn-current">Gebtag</a></span>' navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/balloons-current.svg"/><span class="kn-current">Geburtstage</a></span>'
else: else:
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Birthday">&nbsp;<img class="icon" src="img/balloons.svg"/>Gebtag</a></span>' navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Birthday">&nbsp;<img class="icon" src="img/balloons.svg"/>Geburtstage</a></span>'
# Halbjahresseite # Halbjahresseite
if (bezeichnung=='abgekuerzt'): if (bezeichnung=='abgekuerzt'):
@@ -191,14 +136,6 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
else: else:
myline = str(zschuljahr) + '/' + str((zschuljahr-2000)+1) + ', ' + halbjahr + '. Hj.' myline = str(zschuljahr) + '/' + str((zschuljahr-2000)+1) + ', ' + halbjahr + '. Hj.'
count = 0 headline = '<p class="kn-headline">'+klassekurs_name+' - '+myline+'</p>'
for gruppe in lerngruppen:
count = count + 1
if (gruppe==kursid):
break
mycss = 'h'+str(count) # Headline-CSS hX
headline = '<p class="kn-headline"><span class="'+mycss+'">'+klassekurs_name+'</span> - '+myline+'</p>'
return navileiste + headline return navileiste + headline

View File

@@ -1,117 +0,0 @@
import os
import markdown
import header
import re
def erstelleStartseite(lerngruppen, path, config, inputs):
table = ''
table += '<a name="Home"></a>'
table += header.erstelleHauptnavigation(lerngruppen, path, config, inputs)
allg = inputs["Allgemein"]
schuljahr = allg["schuljahr"]
zschuljahr = int(schuljahr)
halbjahr = allg["halbjahr"]
myline = 'Schuljahr ' + str(zschuljahr) + '/' + str((zschuljahr-2000)+1) + ', ' + halbjahr + '. Hj.'
table += '<h1 class="start">'+myline+'</h1>'
table += '<div class="tt">'
# Markdowndatei einlesen
try:
stundenplandatei = allg['stundenplandatei']
except KeyError:
print('Der Bereichsschlüssel "stundenplandatei" im allgemeinen Bereich existiert nicht in der Input-Datei!')
exit(0)
tt_file = path+stundenplandatei
if (len(stundenplandatei)==0):
print("Stundenplan in der Konfiguration ausgeschaltet, erzeuge Startseite ohne Stundenplan.")
elif (not(os.path.exists(tt_file))):
print("Angegebene Stundenplandatei nicht vorhanden, erzeuge Startseite ohne Stundenplan.")
else:
f = open(tt_file)
text = f.read()
# nach HTML konvertieren
html = markdown.markdown(text, extensions=['tables'])
# mit Markup anreichern zur CSS Formatierung
html = html.replace('<table>','<table class="timetable">')
html = html.replace('''<th style="text-align: center;">''','''<th class="tag">''')
html = html.replace('''<td style="text-align: center;">''','''<td class="tag">''')
html = html.replace('''<tr>
<th class="tag">''','''<tr><th class="stunde">''')
html = html.replace('''<tr>
<td class="tag">''','''<tr><td class="stunde">''')
# ggf. Links zu Lerngruppen einfügen
count = 0
for kursid in lerngruppen:
count = count + 1
mycss = 't'+str(count) # Timetable-CSS tX
try:
kurs_inputs_aktuell = inputs[kursid]
except KeyError:
print('Der Bereichsschlüssel "'+kursid+'" (zur entsprechenden Datei) existiert nicht in der Input-Datei (2)!')
exit(0)
try:
bezeichnung = config["Navigation"]["bezeichnung"]
except KeyError:
print('Der Schlüssel Navigation oder "kurzbezeichnung" existiert nicht in der Device-Datei!')
exit(0)
try:
klassekurs_aktuell = kurs_inputs_aktuell["bezeichnung"]
if (bezeichnung=='kurz'):
klassekurs_print = kurs_inputs_aktuell["kurzbezeichnung"]
elif (bezeichnung=='abgekuerzt'):
klassekurs_print = kurs_inputs_aktuell["abkuerzung"]
else:
klassekurs_print = kurs_inputs_aktuell["bezeichnung"]
except KeyError:
print('Der Schlüssel "bezeichnung" o.ä. fehlt im Bereich "'+kursid+'" der Input-Datei!')
exit(0)
if (bezeichnung=='abgekuerzt'):
html = re.sub('Montag','Mo',html)
html = re.sub('Dienstag','Di',html)
html = re.sub('Mittwoch','Mi',html)
html = re.sub('Donnerstag','Do',html)
html = re.sub('Freitag','Fr',html)
html = re.sub('\\['+kursid+'\\](.+)?<br>','<div class="'+mycss+'"><a href="#'+klassekurs_aktuell+'">'+klassekurs_print+'</a>\\1</div>',html)
html = re.sub('\\['+kursid+'\\](.+)?</td>','<div class="'+mycss+'"><a href="#'+klassekurs_aktuell+'">'+klassekurs_print+'</a>\\1</div></td>',html)
html = re.sub('\\[\\[(.+)?\\]\\](.+)?<br>','<div class="t-empty">\\1 \\2</div>',html)
html = re.sub('\\[\\[(.+)?\\]\\](.+)?</td>','<div class="t-empty">\\1 \\2</div></td>',html)
table += html
table += '</div>'
# Vermerk zum Projekt
table += '<div class="footer">Dieses PDF-Dokument wurde mithilfe des Python-Skripts <a href="https://www.wolfganglezius.de/lehrerpdf/">LehrerPDF</a> von Wolfgang Lezius erzeugt.</div>'
table += '<pdf:nextpage />'
return table

View File

@@ -34,7 +34,7 @@ def erstelleUebersicht(kursid, klassekurs_name, dateien, path, namen, gebdaten,
else: else:
beschriftung_name = "Vorname N." beschriftung_name = "Vorname N."
table += header.erstelleKursnavigation(kursid, 'Übersicht', 'übersicht', klassekurs_name, gebdaten, dateien, path, config, inputs, kurs_inputs) table += header.erstelleKursnavigation(kursid, '', 'übersicht', klassekurs_name, gebdaten, dateien, path, config, inputs, kurs_inputs)
schr_bez = kurs_inputs["schriftlich_bez"] schr_bez = kurs_inputs["schriftlich_bez"]
schr_anzahl = int(kurs_inputs["schriftlich_anzahl"]) schr_anzahl = int(kurs_inputs["schriftlich_anzahl"])