File: //proc/self/root/workspace/create_worksheets.py
from docx import Document
from docx.shared import Cm, Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.section import WD_SECTION
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.enum.table import WD_TABLE_ALIGNMENT, WD_CELL_VERTICAL_ALIGNMENT
from PIL import Image, ImageDraw, ImageFont
import os, textwrap, shutil
TEMPLATE = '/mnt/onedrive/Vorklasse/Material/Deutsch/Das andere Geschlecht.docx'
OUTDIR = '/mnt/onedrive_write/Organisiert/Deutsch/Vorklasse/Sonstige_Dokumente'
IMGDIR = '/workspace/worksheet_images'
os.makedirs(OUTDIR, exist_ok=True)
os.makedirs(IMGDIR, exist_ok=True)
# ---------- helpers ----------
def clear_body(doc):
body = doc._element.body
for child in list(body):
if child.tag.endswith('sectPr'):
continue
body.remove(child)
def set_cell_shading(cell, fill):
tcPr = cell._tc.get_or_add_tcPr()
shd = OxmlElement('w:shd')
shd.set(qn('w:fill'), fill)
tcPr.append(shd)
def set_cell_margins(cell, top=100, start=100, bottom=100, end=100):
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
tcMar = tcPr.first_child_found_in('w:tcMar')
if tcMar is None:
tcMar = OxmlElement('w:tcMar')
tcPr.append(tcMar)
for m, v in [('top', top), ('start', start), ('bottom', bottom), ('end', end)]:
node = tcMar.find(qn(f'w:{m}'))
if node is None:
node = OxmlElement(f'w:{m}')
tcMar.append(node)
node.set(qn('w:w'), str(v))
node.set(qn('w:type'), 'dxa')
def style_base(doc):
styles = doc.styles
styles['Normal'].font.name = 'Aptos'
styles['Normal'].font.size = Pt(11)
def add_title(doc, title, subtitle=None):
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run(title)
r.bold = True
r.font.size = Pt(18)
r.font.color.rgb = RGBColor(74, 56, 90)
if subtitle:
p2 = doc.add_paragraph()
p2.alignment = WD_ALIGN_PARAGRAPH.CENTER
r2 = p2.add_run(subtitle)
r2.italic = True
r2.font.size = Pt(10)
r2.font.color.rgb = RGBColor(90, 90, 90)
def add_info_box(doc, heading, bullets, fill='EEE7F7'):
table = doc.add_table(rows=1, cols=1)
table.alignment = WD_TABLE_ALIGNMENT.CENTER
table.autofit = True
cell = table.cell(0,0)
set_cell_shading(cell, fill)
set_cell_margins(cell, 120, 140, 120, 140)
p = cell.paragraphs[0]
rr = p.add_run(heading + '\n')
rr.bold = True
rr.font.size = Pt(11)
for b in bullets:
pb = cell.add_paragraph(style='List Paragraph')
pb.paragraph_format.left_indent = Cm(0.4)
pb.add_run(b)
doc.add_paragraph()
def add_image(doc, path, width_cm=14.8):
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run()
r.add_picture(path, width=Cm(width_cm))
def add_heading(doc, text):
p = doc.add_paragraph()
r = p.add_run(text)
r.bold = True
r.font.size = Pt(13)
r.font.color.rgb = RGBColor(74, 56, 90)
def add_task_list(doc, tasks):
for i, t in enumerate(tasks, start=1):
p = doc.add_paragraph()
p.paragraph_format.left_indent = Cm(0.3)
p.paragraph_format.first_line_indent = Cm(-0.3)
r1 = p.add_run(f'{i}. ')
r1.bold = True
p.add_run(t)
def add_line_space(doc, lines=3):
for _ in range(lines):
p = doc.add_paragraph('________________________________________________________________________________')
p.runs[0].font.color.rgb = RGBColor(170,170,170)
def generate_ars_image(path):
img = Image.new('RGB', (1600, 900), '#f7f0e6')
d = ImageDraw.Draw(img)
d.rectangle((60,60,1540,840), outline='#8b6b43', width=6)
d.ellipse((110,160,330,380), fill='#d8c3a5', outline='#8b6b43', width=4)
d.rectangle((640,150,1360,680), fill='#fffaf1', outline='#8b6b43', width=5)
for y in range(200, 650, 55):
d.line((700,y,1290,y), fill='#c9b08a', width=3)
d.polygon([(370,650),(520,230),(660,650)], fill='#b44949', outline='#7c2f2f')
d.rectangle((500,610,530,760), fill='#7c2f2f')
d.text((700,95), 'Ovids Liebeskunst', fill='#6b4d2c')
img.save(path)
def generate_minne_image(path):
img = Image.new('RGB', (1600, 900), '#eef2f3')
d = ImageDraw.Draw(img)
d.rectangle((70,70,1530,830), outline='#5d6d7e', width=6)
d.rectangle((160,230,520,760), fill='#c8b38e', outline='#7a5d3b', width=4)
for i in range(6):
x = 190 + i*55
d.rectangle((x,280,x+28,760), fill='#efe7d6', outline='#7a5d3b')
d.polygon([(950,180),(1200,300),(950,430)], fill='#b43d3d', outline='#7d2f2f')
d.line((950,180,950,700), fill='#7d2f2f', width=9)
d.ellipse((760,420,890,550), outline='#6f5b3e', width=5)
d.line((825,550,825,740), fill='#6f5b3e', width=7)
d.line((790,595,860,595), fill='#6f5b3e', width=6)
d.line((825,610,780,700), fill='#6f5b3e', width=6)
d.line((825,610,870,700), fill='#6f5b3e', width=6)
d.arc((690,450,960,690), 200, 340, fill='#b08d57', width=8)
d.text((1030,115), 'Minnesang', fill='#4b5768')
img.save(path)
def generate_slips_image(path):
img = Image.new('RGB', (1600, 900), '#f4f7fb')
d = ImageDraw.Draw(img)
colors = ['#dfe7f2','#efe4f5','#e8f2e3','#f8ead8']
y = 170
for row in range(3):
x = 120
for col in range(4):
d.rounded_rectangle((x,y,x+280,y+140), radius=22, fill=colors[(row+col)%4], outline='#8ba0b5', width=4)
d.ellipse((x+25,y+38,x+75,y+88), outline='#6b7f92', width=4)
d.line((x+85,y+55,x+235,y+55), fill='#90a2b3', width=4)
d.line((x+85,y+85,x+205,y+85), fill='#b1bfcb', width=4)
x += 320
y += 180
d.text((520,70), 'Kennenlernen – Impulse zum Ausschneiden', fill='#536779')
img.save(path)
def make_doc_base():
doc = Document(TEMPLATE)
clear_body(doc)
style_base(doc)
sec = doc.sections[0]
sec.top_margin = Cm(2.2)
sec.bottom_margin = Cm(1.5)
sec.left_margin = Cm(1.9)
sec.right_margin = Cm(1.9)
return doc
# ---------- images ----------
ars_img = os.path.join(IMGDIR, 'ars_amatoria.png')
minne_img = os.path.join(IMGDIR, 'minnesang.png')
slips_img = os.path.join(IMGDIR, 'kennenlernen.png')
generate_ars_image(ars_img)
generate_minne_image(minne_img)
generate_slips_image(slips_img)
# ---------- worksheet 1 ----------
doc = make_doc_base()
add_title(doc, 'Arbeitsblatt: Ovid – Ars Amatoria', 'Vorklasse Deutsch | literarische Liebeskonzepte kritisch betrachten')
add_image(doc, ars_img)
add_info_box(doc, 'Worum geht es hier?', [
'Ovid beschreibt Liebe oft wie eine Kunst mit Regeln, Rollen und Strategien.',
'Wir lesen das heute nicht als Anleitung, sondern als literarischen Blick auf Verführung, Klischees und Geschlechterrollen.',
'Wichtig: Wir prüfen kritisch, was heute problematisch, „cringe“ oder weiterhin wiedererkennbar wirkt.'
])
add_heading(doc, '1. Kurzüberblick')
for text in [
'In der Ars Amatoria erklärt Ovid, wie man Aufmerksamkeit gewinnt, Gespräche beginnt und Interesse weckt. Liebe erscheint dabei oft als kalkuliertes Spiel.',
'Gerade deshalb ist der Text spannend: Er zeigt, wie stark Rollenbilder, Inszenierung und Erwartungen schon in der Antike mitgedacht wurden.'
]:
doc.add_paragraph(text)
add_heading(doc, '2. Beispiele aus Ovid – heute eher „cringe“')
cringe_table = doc.add_table(rows=1, cols=2)
cringe_table.style = 'Table Grid'
cringe_table.alignment = WD_TABLE_ALIGNMENT.CENTER
for i, head in enumerate(['Beispiel/Paraphrase', 'Warum das heute kritisch oder „cringe“ wirkt']):
c = cringe_table.cell(0,i)
c.text = head
set_cell_shading(c, 'EAD9D9')
for a,b in [
('Liebe wird wie ein Feldzug beschrieben: Man soll Taktik anwenden und Chancen berechnen.', 'Gefühle wirken wie Manipulation statt Begegnung auf Augenhöhe.'),
('Äußeres Auftreten wird strategisch geplant: Kleidung, Wirkung und Komplimente sollen gezielt eingesetzt werden.', 'Zu stark kalkuliert wirkt schnell unecht oder aufgesetzt.'),
('Der andere Mensch erscheint teilweise als „Ziel“, das man gewinnen muss.', 'Heute wäre wichtiger: Zustimmung, Respekt, Interesse und echte Kommunikation.')
]:
row = cringe_table.add_row().cells
row[0].text = a
row[1].text = b
doc.add_paragraph()
add_heading(doc, '3. Was daran bis heute als Klischee weiterlebt')
still_table = doc.add_table(rows=1, cols=2)
still_table.style='Table Grid'
for i, head in enumerate(['Beobachtung bei Ovid', 'Warum das heute noch wiedererkennbar ist']):
c=still_table.cell(0,i); c.text=head; set_cell_shading(c,'DDEBD7')
for a,b in [
('Menschen achten auf Sprache, Auftreten und erste Eindrücke.', 'Der erste Eindruck spielt auch heute oft eine große Rolle.'),
('Treffpunkte und Situationen beeinflussen, ob Nähe entsteht.', 'Auch heute wirken Ort, Stimmung und gemeinsamer Kontext mit.'),
('Komplimente und Aufmerksamkeit können Interesse zeigen.', 'Solange sie ehrlich und respektvoll sind, bleiben sie sozial verständlich.')
]:
row=still_table.add_row().cells
row[0].text=a; row[1].text=b
doc.add_paragraph()
add_heading(doc, '4. Arbeitsaufträge')
add_task_list(doc, [
'Markiere in den Beispielen, was eher nach Spiel, Taktik oder Inszenierung klingt.',
'Erkläre in 3–4 Sätzen: Wo würdest du heute eine Grenze zwischen Charme und Manipulation ziehen?',
'Wähle ein Beispiel aus der rechten Tabelle und formuliere es in eine moderne, respektvolle Version um.',
'Diskutiert im Tandem: Warum ist es literarisch interessant, wenn Liebe wie eine „Kunst“ dargestellt wird?'
])
add_heading(doc, '5. Deine Einschätzung')
doc.add_paragraph('Was wirkt an Ovid überraschend modern? Was wirkt deutlich überholt? Begründe kurz.')
add_line_space(doc, 4)
out1 = os.path.join(OUTDIR, 'Arbeitsblatt_Ovid_Ars_Amatoria_Vorklasse.docx')
doc.save(out1)
# ---------- worksheet 2 ----------
doc = make_doc_base()
add_title(doc, 'Arbeitsblatt: Minnesang kompakt', 'Vorklasse Deutsch | Sprache, Werte und Liebeskonzepte im Mittelalter')
add_image(doc, minne_img)
add_info_box(doc, 'Merke dir:', [
'Minnesang ist höfische Liebeslyrik des Mittelalters.',
'Die Sprache ist häufig Mittelhochdeutsch.',
'Liebe wird oft nicht privat-intim, sondern als soziale Haltung und Form dargestellt.'
], fill='E5EDF6')
add_heading(doc, '1. Wichtige Ausspracheregeln (vereinfacht)')
pron = doc.add_table(rows=1, cols=2)
pron.style='Table Grid'
for i, h in enumerate(['Regel', 'Beispiel']):
c=pron.cell(0,i); c.text=h; set_cell_shading(c,'DCE6F2')
for a,b in [
('v wird oft wie f gesprochen', 'vil ≈ fil'),
('z klingt häufig wie ts', 'zît ≈ tsiit'),
('ie ist meist lang', 'liebe ≈ lii-be'),
('ou klingt wie in „Haus“', 'frouwe ≈ frou-we'),
('iu nähert sich einem langen ü', 'liute ≈ lüü-te')
]:
r=pron.add_row().cells; r[0].text=a; r[1].text=b
doc.add_paragraph()
add_heading(doc, '2. Höfische Tugenden')
for t in [
'mâze – Maßhalten, innere Disziplin, angemessenes Verhalten',
'triuwe – Verlässlichkeit, Treue, Bindung an Zusagen',
'êre – Ansehen, Würde, gesellschaftliche Achtung',
'zuht – gutes Benehmen, Selbstkontrolle, kultiviertes Auftreten',
'dienst – bereitwilliges, respektvolles Dienen im höfischen Rahmen'
]:
p=doc.add_paragraph(); p.paragraph_format.left_indent = Cm(0.4); p.add_run('• '+t)
add_heading(doc, '3. Hohe und niedere Minne')
minne = doc.add_table(rows=1, cols=2)
minne.style='Table Grid'
for i,h in enumerate(['Hohe Minne', 'Niedere Minne']):
c=minne.cell(0,i); c.text=h; set_cell_shading(c,'EEE7F7')
row=minne.add_row().cells
row[0].text='Die verehrte Dame steht sozial oder symbolisch „hoch“. Der Sänger dient, wirbt und bleibt oft auf Distanz. Unerfüllbarkeit gehört häufig dazu.'
row[1].text='Liebe erscheint erreichbarer, wechselseitiger oder konkreter. Nähe, Alltag und gegenseitige Erfüllung stehen stärker im Vordergrund.'
doc.add_paragraph()
add_heading(doc, '4. Zeitstrahl zur Minnelyrik')
for item in [
'ca. 1150: frühe Formen höfischer Liebeslyrik entstehen',
'ca. 1170–1200: Blütezeit des klassischen Minnesangs',
'ca. 1200–1230: bekannte Namen wie Walther von der Vogelweide prägen die Gattung',
'ab ca. 1250: Formen verändern sich, Traditionen werden weitergeführt und umgestaltet'
]:
p = doc.add_paragraph()
p.paragraph_format.left_indent = Cm(0.4)
p.add_run('• '+item)
add_heading(doc, '5. Arbeitsaufträge')
add_task_list(doc, [
'Sprich die fünf Ausspracheregeln laut nach und notiere zwei Wörter, die dabei besonders auffallen.',
'Ordne drei höfische Tugenden heutigen Situationen zu: Wo begegnen sie uns noch – wo eher nicht?',
'Erkläre den Unterschied zwischen hoher und niederer Minne in eigenen Worten.',
'Überlege: Warum passt Minnesang gut zu einer höfischen Gesellschaft mit festen Rollen?'
])
add_heading(doc, '6. Mini-Transfer')
doc.add_paragraph('Welche Vorstellungen von Liebe wirken im Minnesang für dich fremd – und welche vielleicht überraschend bekannt?')
add_line_space(doc, 4)
out2 = os.path.join(OUTDIR, 'Arbeitsblatt_Minnesang_Vorklasse.docx')
doc.save(out2)
# ---------- worksheet 3 ----------
doc = make_doc_base()
add_title(doc, 'Ausschneideblatt: Worauf achtest du, wenn du jemanden kennenlernst?', 'Zum Kopieren, Zerschneiden und anonymen Ziehen einzelner Antworten')
add_image(doc, slips_img)
add_info_box(doc, 'Hinweis für die Klasse:', [
'Schreibe leserlich und knapp.',
'Nenne keine Namen.',
'Formuliere so, dass dein Zettel anonym vorgelesen werden kann.'
], fill='E8F1E2')
add_heading(doc, 'Schneide die Zettel an den Linien aus und beantworte jeweils knapp die Frage.')
table = doc.add_table(rows=3, cols=3)
table.style='Table Grid'
table.alignment = WD_TABLE_ALIGNMENT.CENTER
prompts = [
'Worauf achtest du zuerst?',
'Was macht jemanden sympathisch?',
'Was wirkt auf dich eher abschreckend?',
'Ist Humor wichtig? Warum?',
'Welche Rolle spielt Ehrlichkeit?',
'Wie wichtig ist der erste Eindruck?',
'Woran merkst du Respekt?',
'Was findest du eher „cringe“?',
'Was sollte beim Kennenlernen auf keinen Fall fehlen?'
]
idx = 0
for r in range(3):
for c in range(3):
cell = table.cell(r,c)
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.TOP
set_cell_margins(cell,120,120,120,120)
p = cell.paragraphs[0]
run = p.add_run(prompts[idx])
run.bold = True
run.font.size = Pt(11)
idx += 1
for _ in range(4):
pp = cell.add_paragraph('____________________________')
pp.runs[0].font.color.rgb = RGBColor(170,170,170)
doc.add_paragraph()
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run('Nach dem Ausschneiden können die Zettel eingesammelt, gemischt und einzeln vorgelesen werden.')
r.italic = True
r.font.size = Pt(10)
out3 = os.path.join(OUTDIR, 'Ausschneideblatt_Kennenlernen_Vorklasse.docx')
doc.save(out3)
print(out1)
print(out2)
print(out3)