app foldee

This commit is contained in:
marcus.hinz
2026-06-14 12:13:49 +02:00
parent 6d29263392
commit b30e4a7d31
73 changed files with 994 additions and 175 deletions
-1
View File
@@ -1 +0,0 @@
,marcuh,mach12,12.06.2026 09:55,file:///home/marcuh/.config/libreoffice/4;
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env python3
"""Gemeinsames adesso-Styling für die Workshop-Folien.
Teal->Blau-Verlauf, Fira Sans, weiße Shapes + Coral-Akzente,
Header (Pill + Titel) und schlanke Fußzeile (Seitenzahl + adesso)."""
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE
from pptx.oxml.ns import qn
# ---- adesso Palette --------------------------------------------------------
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
INK = RGBColor(0x0E, 0x2A, 0x47) # tiefes Navy Text auf hellen Boxen / dunkle Füllungen
BLUE = RGBColor(0x00, 0x6E, 0xC7)
TEAL = RGBColor(0x28, 0xDC, 0xAA)
GREEN = RGBColor(0x76, 0xC8, 0x00)
CORAL = RGBColor(0xFF, 0x98, 0x68)
PINK = RGBColor(0xF5, 0x66, 0xBA)
TAUPE = RGBColor(0x88, 0x7D, 0x75)
LIGHT = RGBColor(0xD7, 0xE6, 0xF4) # helle, gedämpfte Schrift/Linien auf dem Verlauf
MUTE = RGBColor(0x6B, 0x77, 0x85) # mittleres Grau Text auf weißen Flächen
RECF = RGBColor(0xE6, 0xEF, 0xF8) # helle Kästchen in weißen Boxen
F = "Fira Sans"
FC = "Fira Sans Condensed"
def alpha(shape, opacity_pct):
"""Deckkraft (0-100) auf die Solid-Füllung setzen."""
srgb = shape._element.spPr.find(qn('a:solidFill')).find(qn('a:srgbClr'))
srgb.append(srgb.makeelement(qn('a:alpha'), {'val': str(int(opacity_pct * 1000))}))
def line_alpha(shape, opacity_pct):
ln = shape._element.spPr.find(qn('a:ln'))
srgb = ln.find(qn('a:solidFill')).find(qn('a:srgbClr'))
srgb.append(srgb.makeelement(qn('a:alpha'), {'val': str(int(opacity_pct * 1000))}))
def paint_background(s, width, height):
"""Teal->Blau-Verlauf als Folienhintergrund."""
bgr = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, width, height)
bgr.line.fill.background(); bgr.shadow.inherit = False
bgr.fill.gradient()
try:
bgr.fill.gradient_angle = 90.0
except Exception:
pass
st = bgr.fill.gradient_stops
st[0].position = 0.0; st[0].color.rgb = TEAL
st[1].position = 1.0; st[1].color.rgb = BLUE
return bgr
def chrome(s, title, page):
"""Header (Pill + Titel) + schlanke Fußzeile (Seitenzahl + adesso)."""
pill = s.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE,
Inches(0.55), Inches(0.46), Inches(0.5), Inches(0.26))
pill.fill.background(); pill.line.color.rgb = WHITE; pill.line.width = Pt(1.5)
pill.shadow.inherit = False
try: pill.adjustments[0] = 0.5
except Exception: pass
def _t(x, y, w, h, t, size, color, bold=False, align=PP_ALIGN.LEFT, font=FC):
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
tf.word_wrap = True; tf.margin_left = tf.margin_right = Pt(0)
tf.margin_top = tf.margin_bottom = Pt(0)
p = tf.paragraphs[0]; p.alignment = align
r = p.add_run(); r.text = t
r.font.size = Pt(size); r.font.bold = bold; r.font.name = font; r.font.color.rgb = color
_t(Inches(1.25), Inches(0.34), Inches(11), Inches(0.7), title, 30, WHITE, bold=True)
_t(Inches(0.55), Inches(7.06), Inches(1.0), Inches(0.3), str(page), 11, LIGHT)
_t(Inches(10.95), Inches(6.99), Inches(1.85), Inches(0.4), "adesso", 17, WHITE,
bold=True, align=PP_ALIGN.RIGHT)
+2 -1
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
"""Workshop-Folien 'Vault Technischer Impuls': ruhig, visuell, wenig Text."""
import os
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
@@ -240,6 +241,6 @@ box(s, last_x + Inches(0.75), ey - Inches(0.05), Inches(2.7), Inches(0.95),
caption(s, "Der Zustand entsteht aus den Ereignissen Mehrfaches inklusive.")
out = "/home/marcuh/claude-projects/limbach/Vault_Impuls_Workshop.pptx"
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Vault_Impuls_Workshop.pptx")
prs.save(out)
print("saved", out)
+95 -82
View File
@@ -1,31 +1,21 @@
#!/usr/bin/env python3
"""Folie 2 Grenzen der Vault-Integration. Kette: Auftrag -> altes LIS ->
Schattenbuchhaltung/Metadaten -> Vault (am Ende). Der Layer wird zum SPOT."""
"""Folie 2 Grenzen der Vault-Integration (adesso-Styling).
Kette: Auftrag -> Auftragsannahme -> Schattenbuchhaltung (SPOT) -> Vault ->
Zusammenführung."""
import os
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE
INK = RGBColor(0x2A, 0x2F, 0x3A)
NAVY = RGBColor(0x1F, 0x3A, 0x5F)
ACCENT = RGBColor(0xC0, 0x49, 0x2F)
MUTE = RGBColor(0x8A, 0x93, 0xA0)
LINEC = RGBColor(0xC3, 0xC9, 0xD1)
FRAME = RGBColor(0xF4, 0xF6, 0xF8)
TINT_R = RGBColor(0xF6, 0xE5, 0xDF)
BG = RGBColor(0xFF, 0xFF, 0xFF)
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
F = "Calibri"
from adesso_style import (WHITE, INK, CORAL, LIGHT, RECF, F, FC,
alpha, line_alpha, paint_background, chrome)
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
s = prs.slides.add_slide(prs.slide_layouts[6])
bgr = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, prs.slide_height)
bgr.fill.solid(); bgr.fill.fore_color.rgb = BG; bgr.line.fill.background()
bgr.shadow.inherit = False
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0):
@@ -39,62 +29,62 @@ def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0):
return sh
def boxtext(sh, t, size=14, color=INK, bold=False):
def boxtext(sh, t, size=14, color=INK, bold=False, font=F):
tf = sh.text_frame; tf.word_wrap = True
tf.vertical_anchor = MSO_ANCHOR.MIDDLE
tf.margin_left = tf.margin_right = Pt(4); tf.margin_top = tf.margin_bottom = Pt(1)
p = tf.paragraphs[0]; p.alignment = PP_ALIGN.CENTER
r = p.add_run(); r.text = t
r.font.size = Pt(size); r.font.bold = bold; r.font.name = F; r.font.color.rgb = color
r.font.size = Pt(size); r.font.bold = bold; r.font.name = font; r.font.color.rgb = color
def txt(x, y, w, h, t, size=14, color=INK, bold=False, italic=False,
align=PP_ALIGN.LEFT, spc=None, lead=1.1, anchor=MSO_ANCHOR.TOP):
align=PP_ALIGN.LEFT, spc=None, lead=1.1, anchor=MSO_ANCHOR.TOP, font=F):
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
tf.word_wrap = True; tf.vertical_anchor = anchor
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
p = tf.paragraphs[0]; p.alignment = align; p.line_spacing = lead
r = p.add_run(); r.text = t
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
r.font.name = F; r.font.color.rgb = color
r.font.name = font; r.font.color.rgb = color
if spc: r.font._rPr.set('spc', str(spc))
return tb
# ---- Kopf ------------------------------------------------------------------
txt(Inches(0.95), Inches(0.32), Inches(8), Inches(0.35), "INTEGRATION",
size=12.5, color=ACCENT, bold=True, spc=240)
txt(Inches(0.95), Inches(0.62), Inches(11.5), Inches(0.85), "Grenzen der Vault-Integration?",
size=31, color=NAVY, bold=True)
shp(MSO_SHAPE.RECTANGLE, Inches(0.95), Inches(1.34), Inches(0.6), Pt(4), fill=ACCENT)
paint_background(s, prs.slide_width, prs.slide_height)
chrome(s, "Grenzen der Vault-Integration?", 2)
# ---- Linke Spalte ----------------------------------------------------------
def claim(y, t, bold=False, sub=None):
shp(MSO_SHAPE.RECTANGLE, Inches(0.95), y + Inches(0.08), Inches(0.14), Inches(0.14), fill=ACCENT)
txt(Inches(1.28), y, Inches(4.5), Inches(0.4), t, size=16.5, color=INK, bold=bold)
shp(MSO_SHAPE.RECTANGLE, Inches(0.95), y + Inches(0.08), Inches(0.14), Inches(0.14), fill=CORAL)
txt(Inches(1.28), y, Inches(4.5), Inches(0.4), t, size=16.5, color=WHITE, bold=bold)
if sub:
txt(Inches(1.28), y + Inches(0.34), Inches(4.5), Inches(0.32), sub,
size=12.5, color=MUTE, italic=True)
size=12.5, color=LIGHT, italic=True)
claim(Inches(2.2), "Middleware kapselt den Rand den Kern nicht", bold=True)
claim(Inches(2.95), "1:n geht nur als Schattenmodell",
claim(Inches(2.95), "Mischaufträge nur als Schattenmodell",
sub="aufwändig · fragil · fehleranfällig")
claim(Inches(3.95), "die Fachwahrheit verlässt den Kern")
shp(MSO_SHAPE.RECTANGLE, Inches(0.95), Inches(4.95), Inches(0.5), Pt(3.5), fill=ACCENT)
shp(MSO_SHAPE.RECTANGLE, Inches(0.95), Inches(4.95), Inches(0.5), Pt(3.5), fill=CORAL)
txt(Inches(0.95), Inches(5.12), Inches(4.85), Inches(1.1),
"Die Schattenbuchhaltung wird zum Single Point of Truth nicht Vault.",
size=19, color=NAVY, bold=True, lead=1.08)
size=19, color=WHITE, bold=True, lead=1.08, font=FC)
txt(Inches(0.95), Inches(6.45), Inches(4.85), Inches(0.4),
"Genau die Rolle, die Vault halten müsste.", size=13.5, color=MUTE, italic=True)
"Genau die Rolle, die Vault halten müsste.", size=13.5, color=LIGHT, italic=True)
# ===========================================================================
# RECHTS: Kette Auftrag -> altes LIS -> Layer (SPOT) -> Vault (Ende)
# RECHTS: Kette Auftrag -> Auftragsannahme -> SPOT -> Vault -> Zusammenführung
# ===========================================================================
fx, fy, fw, fh = Inches(6.25), Inches(2.4), Inches(5.9), Inches(4.55)
shp(MSO_SHAPE.ROUNDED_RECTANGLE, fx, fy, fw, fh, fill=FRAME, line=LINEC, lw=Pt(1.5))
txt(fx + Inches(0.3), fy + Inches(0.14), fw - Inches(0.6), Inches(0.3),
"Auftragsweg hin und zurück durch den Layer", size=12.5, color=NAVY, bold=True)
fx, fy, fw, fh = Inches(6.25), Inches(2.1), Inches(5.9), Inches(4.72)
panel = shp(MSO_SHAPE.ROUNDED_RECTANGLE, fx, fy, fw, fh, fill=WHITE)
alpha(panel, 10)
panel.line.color.rgb = WHITE; panel.line.width = Pt(1)
line_alpha(panel, 35)
txt(fx + Inches(0.3), fy + Inches(0.12), fw - Inches(0.6), Inches(0.3),
"Auftragsweg hin und zurück durch den Layer", size=12.5, color=WHITE, bold=True)
cxc = fx + Inches(2.05)
bw = Inches(2.7)
@@ -102,60 +92,83 @@ bx = cxc - bw / 2
def down(y, label=None):
shp(MSO_SHAPE.DOWN_ARROW, cxc - Inches(0.11), y, Inches(0.22), Inches(0.26), fill=MUTE)
shp(MSO_SHAPE.DOWN_ARROW, cxc - Inches(0.11), y, Inches(0.22), Inches(0.22), fill=LIGHT)
if label:
txt(cxc + Inches(0.22), y - Inches(0.02), Inches(1.6), Inches(0.3), label,
size=11, color=MUTE, italic=True, anchor=MSO_ANCHOR.MIDDLE)
txt(cxc + Inches(0.22), y - Inches(0.02), Inches(1.7), Inches(0.3), label,
size=11, color=LIGHT, italic=True, anchor=MSO_ANCHOR.MIDDLE)
# 1) Auftrag
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, fy + Inches(0.52), bw, Inches(0.48), fill=BG, line=LINEC)
boxtext(b, "Auftrag · Mischauftrag (1:n)", size=12.5, color=INK, bold=True)
down(fy + Inches(1.02))
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, fy + Inches(0.44), bw, Inches(0.40), fill=WHITE)
boxtext(b, "Auftrag · Mischauftrag", size=12.5, color=INK, bold=True)
down(fy + Inches(0.86))
# 2) Altes LIS
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, fy + Inches(1.3), bw, Inches(0.5), fill=NAVY)
boxtext(b, "Altes LIS · nimmt 1:n an", size=13, color=WHITE, bold=True)
down(fy + Inches(1.82), "Magic")
# 2) Auftragsannahme (ersetzt altes LIS)
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, fy + Inches(1.06), bw, Inches(0.40), fill=WHITE)
boxtext(b, "Auftragsannahme", size=13, color=INK, bold=True)
down(fy + Inches(1.48), "Magic")
# 3) Schattenbuchhaltung = SPOT
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx - Inches(0.15), fy + Inches(2.1), bw + Inches(0.3),
Inches(0.78), fill=TINT_R, line=ACCENT, lw=Pt(2))
txt(bx - Inches(0.15), fy + Inches(2.18), bw + Inches(0.3), Inches(0.32),
"Schattenbuchhaltung / Metadaten", size=13, color=ACCENT, bold=True, align=PP_ALIGN.CENTER)
txt(bx - Inches(0.15), fy + Inches(2.52), bw + Inches(0.3), Inches(0.3), "Mapping 1 ↔ 3",
size=12, color=INK, align=PP_ALIGN.CENTER)
# aktiver SPOT-Stern
shp(MSO_SHAPE.STAR_5_POINT, fx + fw - Inches(0.78), fy + Inches(2.18), Inches(0.5), Inches(0.5),
fill=ACCENT)
txt(fx + fw - Inches(2.55), fy + Inches(2.7), Inches(1.75), Inches(0.28), "Single Point of Truth",
size=10.5, color=ACCENT, bold=True, align=PP_ALIGN.RIGHT)
down(fy + Inches(2.9), "1 → 3, Vault-kompatibel")
# 3) Schattenbuchhaltung = Rahmen um den Vault-Kasten
frx, fry = bx - Inches(0.22), fy + Inches(1.72)
frw, frh = bw + Inches(0.50), Inches(2.22)
frame = shp(MSO_SHAPE.ROUNDED_RECTANGLE, frx, fry, frw, frh,
fill=RGBColor(0xFF, 0xE3, 0x9B))
alpha(frame, 22)
frame.line.color.rgb = CORAL; frame.line.width = Pt(2)
# 4) Vault am Ende
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, fy + Inches(3.18), bw, Inches(0.82), fill=NAVY)
txt(bx, fy + Inches(3.24), bw, Inches(0.3), "Vault · 1:1 · Speicher",
size=13, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
# Überschrift + Positions-Mapping (oben im Rahmen)
txt(frx, fy + Inches(1.78), frw, Inches(0.28), "Schattenbuchhaltung",
size=13, color=CORAL, bold=True, align=PP_ALIGN.CENTER)
txt(frx, fy + Inches(2.07), frw, Inches(0.24), "Positions-Mapping",
size=11.5, color=WHITE, align=PP_ALIGN.CENTER)
# aktiver SPOT-Stern (rechts neben dem Rahmen)
shp(MSO_SHAPE.STAR_5_POINT, Inches(10.75), fy + Inches(1.80), Inches(0.5), Inches(0.5), fill=CORAL)
txt(Inches(9.95), fy + Inches(2.32), Inches(2.1), Inches(0.28), "Single Point of Truth",
size=10.5, color=CORAL, bold=True, align=PP_ALIGN.CENTER)
down(fy + Inches(2.33))
# 4) Vault speichert (aufgesplittet) im Rahmen
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, fy + Inches(2.50), bw, Inches(0.70), fill=WHITE)
txt(bx, fy + Inches(2.55), bw, Inches(0.3), "Vault · 1:1 · Speicher",
size=13, color=INK, bold=True, align=PP_ALIGN.CENTER)
for k in range(3):
shp(MSO_SHAPE.ROUNDED_RECTANGLE, cxc - Inches(1.08) + k * Inches(0.78),
fy + Inches(3.58), Inches(0.62), Inches(0.3), fill=RGBColor(0x34, 0x4E, 0x70))
txt(cxc - Inches(1.08) + k * Inches(0.78), fy + Inches(3.58), Inches(0.62), Inches(0.3),
"Rec", size=9.5, color=WHITE, align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE)
# Geist-Stern (durchgestrichen) bei Vault
gx = fx + fw - Inches(0.74)
shp(MSO_SHAPE.STAR_5_POINT, gx, fy + Inches(3.32), Inches(0.44), Inches(0.44),
fill=BG, line=LINEC, lw=Pt(1.25))
shp(MSO_SHAPE.RECTANGLE, gx - Inches(0.02), fy + Inches(3.52), Inches(0.48), Pt(2),
fill=ACCENT, rot=20)
txt(fx + fw - Inches(2.45), fy + Inches(3.3), Inches(1.65), Inches(0.4),
"müsste hier liegen", size=10, color=MUTE, align=PP_ALIGN.RIGHT)
fy + Inches(2.87), Inches(0.62), Inches(0.3), fill=RECF)
txt(cxc - Inches(1.08) + k * Inches(0.78), fy + Inches(2.87), Inches(0.62), Inches(0.3),
"Rec", size=9.5, color=INK, align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE)
# Geist-Stern (durchgestrichen) die Wahrheit müsste hier liegen
gx = Inches(10.79)
gs = shp(MSO_SHAPE.STAR_5_POINT, gx, fy + Inches(2.55), Inches(0.42), Inches(0.42))
gs.fill.background(); gs.line.color.rgb = LIGHT; gs.line.width = Pt(1.25)
shp(MSO_SHAPE.RECTANGLE, gx - Inches(0.02), fy + Inches(2.73), Inches(0.46), Pt(2),
fill=CORAL, rot=20)
txt(Inches(9.95), fy + Inches(3.02), Inches(2.1), Inches(0.3), "müsste hier liegen",
size=10, color=LIGHT, align=PP_ALIGN.CENTER)
down(fy + Inches(3.22))
# Rückweg (Lesen) Pfeil links nach oben
shp(MSO_SHAPE.UP_ARROW, fx + Inches(0.34), fy + Inches(1.45), Inches(0.26), Inches(2.45),
fill=RGBColor(0xD8, 0xCB, 0xC6))
txt(fx + Inches(0.1), fy + Inches(3.95), Inches(1.55), Inches(0.5),
"Lesen: zurück, wieder LIS-kompatibel", size=9.5, color=ACCENT, align=PP_ALIGN.LEFT, lead=1.0)
# 5) Daten zusammenführen (unten im Rahmen)
txt(frx, fy + Inches(3.42), frw, Inches(0.28), "Daten Zusammenführen",
size=12.5, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
out = "/home/marcuh/claude-projects/limbach/Folie2.pptx"
# 6) Weiterverarbeitung grauer Pfeil + weißer Kasten unter dem Rahmen
shp(MSO_SHAPE.DOWN_ARROW, cxc - Inches(0.11), fy + Inches(4.00), Inches(0.22), Inches(0.22),
fill=RGBColor(0x8C, 0x8C, 0x8C))
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, fy + Inches(4.26), bw, Inches(0.40), fill=WHITE)
boxtext(b, "Weiterverarbeitung", size=12.5, color=INK, bold=True)
# Rückweg (Lesen) Pfeil links nach oben, Label vertikal daneben
ua = shp(MSO_SHAPE.UP_ARROW, fx + Inches(0.08), fy + Inches(1.55), Inches(0.26), Inches(2.30),
fill=LIGHT)
alpha(ua, 55)
lt = s.shapes.add_textbox(fx - Inches(0.95), fy + Inches(2.40), Inches(2.2), Inches(0.3))
ltf = lt.text_frame; ltf.word_wrap = False
ltf.margin_left = ltf.margin_right = ltf.margin_top = ltf.margin_bottom = Pt(0)
lp = ltf.paragraphs[0]; lp.alignment = PP_ALIGN.CENTER
lr = lp.add_run(); lr.text = "Lesen: zurück durch den Layer"
lr.font.size = Pt(9.5); lr.font.name = F; lr.font.color.rgb = CORAL
lt.rotation = 270
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie2.pptx")
prs.save(out)
print("saved", out)
+62 -47
View File
@@ -2,35 +2,32 @@
"""Folie 3 LIS mit Umsystemen (Adapter, links/rechts) und andockenden Modulen
(unten), unter einer Steuerungs-/Governance-Schicht; weitere LIS angedeutet."""
import os
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, MUTE, RECF,
F, FC, paint_background, chrome)
INK = RGBColor(0x2A, 0x2F, 0x3A)
NAVY = RGBColor(0x1F, 0x3A, 0x5F)
ACCENT = RGBColor(0xC0, 0x49, 0x2F)
TEAL = RGBColor(0x2F, 0x8F, 0x83)
AMBER = RGBColor(0xA9, 0x73, 0x22)
MUTE = RGBColor(0x8A, 0x93, 0xA0)
LINEC = RGBColor(0xC3, 0xC9, 0xD1)
HINT = RGBColor(0xEE, 0xF1, 0xF4)
HINTL = RGBColor(0xCB, 0xD2, 0xDA)
TINT_T = RGBColor(0xDD, 0xEC, 0xEA)
TINT_A = RGBColor(0xF3, 0xE8, 0xD2)
UMS = RGBColor(0xEC, 0xEE, 0xF1)
BG = RGBColor(0xFF, 0xFF, 0xFF)
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
F = "Calibri"
# Rollen-Mapping auf die adesso-Palette
NAVY = INK # dunkle Strukturelemente (Bar, LIS-Kern)
ACCENT = CORAL # Adapter-Linien
AMBER = GREEN # zweites Modul
LINEC = LIGHT # Verbinder / feine Linien
HINT = RGBColor(0xE6, 0xEF, 0xF8) # helle "weitere LIS"-Karten
HINTL = RGBColor(0xC4, 0xD6, 0xE8)
TINT_T = WHITE # Modul-Boxen weiß
TINT_A = WHITE
UMS = WHITE # Umsystem-Boxen weiß
BG = WHITE
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
s = prs.slides.add_slide(prs.slide_layouts[6])
bgr = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, prs.slide_height)
bgr.fill.solid(); bgr.fill.fore_color.rgb = BG; bgr.line.fill.background()
bgr.shadow.inherit = False
paint_background(s, prs.slide_width, prs.slide_height)
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0):
@@ -75,11 +72,7 @@ def vline(x, y, h, color=LINEC, weight=Pt(1.4)):
# ---- Kopf ------------------------------------------------------------------
txt(Inches(0.95), Inches(0.32), Inches(8), Inches(0.35), "ARCHITEKTUR",
size=12.5, color=ACCENT, bold=True, spc=240)
txt(Inches(0.95), Inches(0.62), Inches(11), Inches(0.85), "Offen und gesteuert",
size=31, color=NAVY, bold=True)
shp(MSO_SHAPE.RECTANGLE, Inches(0.95), Inches(1.34), Inches(0.6), Pt(4), fill=ACCENT)
chrome(s, "Offen und gesteuert", 3)
x0, x1 = Inches(0.95), Inches(12.38)
@@ -144,6 +137,14 @@ core_y, core_h = Inches(4.3), Inches(1.2)
core_cx = core_x + core_w / 2
core_by = core_y + core_h
# Adapter-Schicht: echte Schicht als Hülle um den Kern (Trennung)
lay_pad_x, lay_pad_t = Inches(0.24), Inches(0.30)
lay_x = core_x - lay_pad_x
lay_w = core_w + lay_pad_x * 2
lay_y = core_y - lay_pad_t
lay_h = core_h + lay_pad_t
lay_right = lay_x + lay_w
def adapter(xc, yc):
shp(MSO_SHAPE.ROUNDED_RECTANGLE, xc - Inches(0.10), yc - Inches(0.11),
@@ -185,8 +186,12 @@ def icon_dfu(ix, iy): # DFÜ
fill=ACCENT)
# Governance -> LIS
vline(core_cx, gov_y + Inches(0.07), core_y - (gov_y + Inches(0.07)), color=LINEC, weight=Pt(1))
g = Inches(0.10) # Abstand Adapter-Linie <-> LIS
th = Inches(0.08) # Dicke der roten Adapter-Linie
# Governance -> obere Adapter-Linie am Kern
vline(core_cx, gov_y + Inches(0.07), (core_y - g - th) - (gov_y + Inches(0.07)),
color=LINEC, weight=Pt(1))
uw, uh = Inches(1.55), Inches(0.6)
@@ -198,37 +203,50 @@ def ums_box(bx, yc, name, icon_fn):
size=12, color=INK, align=PP_ALIGN.LEFT)
# Umsysteme links
# Umsysteme links -> Adapter-Schichten am linken Kernrand
lx = Inches(0.8)
ums_box(lx, Inches(4.6), "Anlieferung", icon_truck)
ums_box(lx, Inches(5.2), "DFÜ", icon_dfu)
for yc in (Inches(4.6), Inches(5.2)):
hline(lx + uw, yc, core_x - (lx + uw))
adapter(core_x - Inches(0.16), yc)
hline(lx + uw, yc, (core_x - g - th) - (lx + uw))
# Umsystem rechts
# Umsystem rechts -> Adapter-Linie am rechten Kernrand
gx = Inches(6.65)
ums_box(gx, Inches(4.9), "Geräte", icon_device)
hline(core_x + core_w, Inches(4.9), gx - (core_x + core_w))
adapter(core_x + core_w + Inches(0.16), Inches(4.9))
hline(core_x + core_w + g + th, Inches(4.9), gx - (core_x + core_w + g + th))
# LIS (kompakt, solide)
# ---- LIS-Kern -------------------------------------------------------------
shp(MSO_SHAPE.ROUNDED_RECTANGLE, core_x, core_y, core_w, core_h, fill=NAVY)
sh = shp(MSO_SHAPE.ROUNDED_RECTANGLE, core_x, core_y, core_w, core_h, fill=NAVY)
boxtext(sh, "LIS", size=22, color=WHITE, bold=True)
# Module unten (andockend)
# ---- 5 Adapter-Linien je Schnittstelle eine, mit Abstand zum Kern -------
def rbar_v(outer_x, yc, h=Inches(0.55)): # vertikal, linker/rechter Rand
shp(MSO_SHAPE.RECTANGLE, outer_x, yc - h / 2, th, h, fill=ACCENT)
def rbar_h(xc, outer_y, w): # horizontal, oben/unten
shp(MSO_SHAPE.RECTANGLE, xc - w / 2, outer_y, w, th, fill=ACCENT)
rbar_v(core_x - g - th, Inches(4.6)) # 1) Anlieferung
rbar_v(core_x - g - th, Inches(5.2)) # 2) DFÜ
rbar_h(core_cx, core_y - g - th, Inches(1.15)) # 3) nach oben (Steuerung)
rbar_v(core_x + core_w + g, Inches(4.9)) # 4) Geräte
rbar_h(core_cx, core_by + g, core_w - Inches(0.2)) # 5) Fachliche Verarbeitung
# Fachliche Verarbeitung (unten): Module an der unteren Adapter-Linie
mw, mh = Inches(1.7), Inches(0.6)
my = Inches(6.05)
for nm, fill, tc, mcx in [("Hochdurchsatz", TINT_T, TEAL, Inches(3.85)),
("Spezial", TINT_A, AMBER, Inches(5.85))]:
vline(mcx, core_by, my - core_by, color=LINEC, weight=Pt(1))
dock(mcx, core_by + (my - core_by) / 2)
sh = shp(MSO_SHAPE.ROUNDED_RECTANGLE, mcx - mw / 2, my, mw, mh, fill=fill, line=tc, lw=Pt(1.25))
boxtext(sh, nm, size=12.5, color=tc, bold=True)
vline(mcx, core_by + g + th, my - (core_by + g + th), color=LINEC, weight=Pt(1))
sh = shp(MSO_SHAPE.ROUNDED_RECTANGLE, mcx - mw / 2, my, mw, mh, fill=fill, line=tc, lw=Pt(1.5))
boxtext(sh, nm, size=12.5, color=INK, bold=True)
txt(Inches(2.9), my + mh + Inches(0.12), Inches(4.0), Inches(0.3), "eigene Module",
size=12, color=MUTE, bold=True, align=PP_ALIGN.CENTER)
txt(Inches(2.9), my + mh + Inches(0.12), Inches(4.0), Inches(0.3), "Fachliche Verarbeitung",
size=12, color=LIGHT, bold=True, align=PP_ALIGN.CENTER)
# ===========================================================================
@@ -252,17 +270,14 @@ mini_lis(Inches(10.0), Inches(4.75), faded=False)
vline(Inches(10.0) + hw_ / 2, gov_y + Inches(0.07), Inches(4.75) - (gov_y + Inches(0.07)),
color=LINEC, weight=Pt(1))
txt(Inches(9.9), Inches(4.35) + hh_ + Inches(0.2), Inches(2.4), Inches(0.35), "weitere LIS",
size=13, color=MUTE, align=PP_ALIGN.CENTER)
size=13, color=LIGHT, align=PP_ALIGN.CENTER)
# ---- Mini-Legende ----------------------------------------------------------
ly = Inches(7.05)
adapter(Inches(7.35), ly)
txt(Inches(7.55), ly - Inches(0.16), Inches(2.1), Inches(0.32), "Adapter (Umsysteme)",
size=11.5, color=MUTE)
dock(Inches(9.65), ly)
txt(Inches(9.85), ly - Inches(0.16), Inches(2.1), Inches(0.32), "Andocken (Module)",
size=11.5, color=MUTE)
shp(MSO_SHAPE.RECTANGLE, Inches(7.55), ly - Inches(0.11), th, Inches(0.22), fill=ACCENT)
txt(Inches(7.8), ly - Inches(0.16), Inches(3.2), Inches(0.32),
"Adapter-Schicht je Schnittstelle eine", size=11.5, color=LIGHT)
out = "/home/marcuh/claude-projects/limbach/Folie3.pptx"
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie3.pptx")
prs.save(out)
print("saved", out)
+180
View File
@@ -0,0 +1,180 @@
#!/usr/bin/env python3
"""Folie 4 (eingehängt nach Folie 3) Architektur der Modularisierung:
Modularer Monolith vs. Microservices, anschaulich im Containerumfeld.
Links: 1 Container, Module mit In-Process-Calls, 1 geteilte DB.
Rechts: N Container, Services über Netzwerk, DB je Service.
Unten: kompakte Gegenüberstellung der wesentlichen Unterschiede."""
import os
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, MUTE, RECF,
F, FC, paint_background, chrome)
NAVY = INK
ACCENT = CORAL
LINEC = LIGHT
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
s = prs.slides.add_slide(prs.slide_layouts[6])
paint_background(s, prs.slide_width, prs.slide_height)
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0):
sh = s.shapes.add_shape(kind, x, y, w, h)
if fill is None: sh.fill.background()
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
if line is None: sh.line.fill.background()
else: sh.line.color.rgb = line; sh.line.width = lw
if rot: sh.rotation = rot
sh.shadow.inherit = False
return sh
def boxtext(sh, t, size=14, color=INK, bold=False):
tf = sh.text_frame; tf.word_wrap = True
tf.vertical_anchor = MSO_ANCHOR.MIDDLE
tf.margin_left = tf.margin_right = Pt(3); tf.margin_top = tf.margin_bottom = Pt(1)
p = tf.paragraphs[0]; p.alignment = PP_ALIGN.CENTER
r = p.add_run(); r.text = t
r.font.size = Pt(size); r.font.bold = bold; r.font.name = F; r.font.color.rgb = color
def txt(x, y, w, h, t, size=14, color=INK, bold=False, italic=False,
align=PP_ALIGN.LEFT, spc=None):
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
tf.word_wrap = True; tf.vertical_anchor = MSO_ANCHOR.MIDDLE
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
p = tf.paragraphs[0]; p.alignment = align
r = p.add_run(); r.text = t
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
r.font.name = F; r.font.color.rgb = color
if spc: r.font._rPr.set('spc', str(spc))
return tb
def vline(x, y, h, color=LINEC, weight=Pt(1.4)):
shp(MSO_SHAPE.RECTANGLE, x - weight / 2, y, weight, h, fill=color)
def hline(x, y, w, color=LINEC, weight=Pt(1.4)):
shp(MSO_SHAPE.RECTANGLE, x, y - weight / 2, w, weight, fill=color)
# ---- Kopf + Kernaussage ----------------------------------------------------
chrome(s, "Architektur der Modularisierung", 4)
txt(Inches(1.25), Inches(0.98), Inches(11.6), Inches(0.34),
"Gleiche fachlichen Schnitte der Unterschied ist die Laufzeit- und Deployment-Grenze.",
size=14, color=LIGHT, italic=True)
DOT = [TEAL, GREEN, BLUE] # gleiche Module/Services beidseitig farblich verankert
LET = ["A", "B", "C"]
# ===========================================================================
# Spalten-Titel
# ===========================================================================
cL = Inches(3.6) # Mittelpunkt linke Spalte
cR = Inches(9.75) # Mittelpunkt rechte Spalte
txt(Inches(0.95), Inches(1.5), Inches(5.3), Inches(0.32), "Modularer Monolith",
size=18, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
txt(Inches(0.95), Inches(1.84), Inches(5.3), Inches(0.26), "1 Deployable · 1 Prozess",
size=11.5, color=LIGHT, align=PP_ALIGN.CENTER)
txt(Inches(7.0), Inches(1.5), Inches(5.5), Inches(0.32), "Microservices",
size=18, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
txt(Inches(7.0), Inches(1.84), Inches(5.5), Inches(0.26), "N Deployables · N Prozesse",
size=11.5, color=LIGHT, align=PP_ALIGN.CENTER)
# ===========================================================================
# LINKS Modularer Monolith: 1 Container, Module, geteilte DB
# ===========================================================================
cx_x, cx_w, cx_y, cx_h = Inches(0.95), Inches(5.3), Inches(2.2), Inches(1.6)
shp(MSO_SHAPE.ROUNDED_RECTANGLE, cx_x, cx_y, cx_w, cx_h, line=WHITE, lw=Pt(1.5))
txt(cx_x + Inches(0.15), cx_y + Inches(0.05), Inches(2.0), Inches(0.26), "1 Container",
size=11, color=LIGHT, bold=True)
mw, mh, my = Inches(1.35), Inches(0.8), Inches(2.62)
mcx = [Inches(2.05), Inches(3.6), Inches(5.15)]
for i, mx in enumerate(mcx):
sh = shp(MSO_SHAPE.ROUNDED_RECTANGLE, mx - mw / 2, my, mw, mh, fill=WHITE, line=LINEC, lw=Pt(1))
boxtext(sh, "Modul " + LET[i], size=13, color=INK, bold=True)
shp(MSO_SHAPE.OVAL, mx - Inches(0.07), my + Inches(0.12), Inches(0.14), Inches(0.14), fill=DOT[i])
# In-Process-Pfeile zwischen den Modulen
for ax in (Inches(2.725), Inches(4.275)):
shp(MSO_SHAPE.RIGHT_ARROW, ax, my + mh / 2 - Inches(0.09), Inches(0.2), Inches(0.18), fill=ACCENT)
txt(cx_x, cx_y + cx_h - Inches(0.34), cx_w, Inches(0.26), "In-Process-Aufrufe · Nanosekunden",
size=11, color=LIGHT, align=PP_ALIGN.CENTER)
# geteilte Datenbank
db_w, db_h, db_y = Inches(1.5), Inches(0.95), Inches(4.0)
vline(cL, cx_y + cx_h, db_y - (cx_y + cx_h), color=LINEC, weight=Pt(1.4))
sh = shp(MSO_SHAPE.CAN, cL - db_w / 2, db_y, db_w, db_h, fill=WHITE, line=LINEC, lw=Pt(1))
boxtext(sh, "DB", size=14, color=INK, bold=True)
txt(cx_x, db_y + db_h + Inches(0.06), cx_w, Inches(0.28), "1 geteilte Datenbank",
size=12.5, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
# ===========================================================================
# RECHTS Microservices: Netzwerk-Bus, N Container, DB je Service
# ===========================================================================
bar_x, bar_w, bar_y, bar_h = Inches(7.1), Inches(5.3), Inches(2.2), Inches(0.26)
bar = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bar_x, bar_y, bar_w, bar_h, fill=NAVY)
boxtext(bar, "Netzwerk-Grenze · HTTP / gRPC / Events", size=11, color=WHITE, bold=True)
scx = [Inches(7.95), Inches(9.75), Inches(11.55)]
sc_w, sc_h, sc_y = Inches(1.5), Inches(1.2), Inches(2.62)
sdb_w, sdb_h, sdb_y = Inches(0.85), Inches(0.7), Inches(3.97)
for i, cx in enumerate(scx):
vline(cx, bar_y + bar_h, sc_y - (bar_y + bar_h), color=LINEC, weight=Pt(1.1))
shp(MSO_SHAPE.ROUNDED_RECTANGLE, cx - sc_w / 2, sc_y, sc_w, sc_h, line=WHITE, lw=Pt(1.5))
sh = shp(MSO_SHAPE.ROUNDED_RECTANGLE, cx - Inches(0.55), sc_y + Inches(0.3),
Inches(1.1), Inches(0.62), fill=WHITE, line=LINEC, lw=Pt(1))
boxtext(sh, "Svc " + LET[i], size=12.5, color=INK, bold=True)
shp(MSO_SHAPE.OVAL, cx - Inches(0.06), sc_y + Inches(0.4), Inches(0.12), Inches(0.12), fill=DOT[i])
# eigene DB je Service
vline(cx, sc_y + sc_h, sdb_y - (sc_y + sc_h), color=LINEC, weight=Pt(1.1))
sh = shp(MSO_SHAPE.CAN, cx - sdb_w / 2, sdb_y, sdb_w, sdb_h, fill=WHITE, line=LINEC, lw=Pt(1))
boxtext(sh, "DB", size=11, color=INK, bold=True)
txt(bar_x, sdb_y + sdb_h + Inches(0.06), bar_w, Inches(0.28), "Datenbank je Service",
size=12.5, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
# ===========================================================================
# Trenner + vs.
# ===========================================================================
vline(Inches(6.65), Inches(1.55), Inches(3.5), color=LINEC, weight=Pt(1))
vs = shp(MSO_SHAPE.OVAL, Inches(6.65) - Inches(0.31), Inches(3.05), Inches(0.62), Inches(0.46),
line=WHITE, lw=Pt(1.5))
vs.fill.background()
boxtext(vs, "vs.", size=13, color=WHITE, bold=True)
# ===========================================================================
# Gegenüberstellung wesentliche Unterschiede
# ===========================================================================
rows = [
("Skalierung", "als Ganzes (mehr Replicas)", "je Service gezielt"),
("Datenhaltung", "1 geteilte DB", "DB je Service"),
("Deployment", "gemeinsam, 1 Pipeline", "unabhängig je Service"),
("Konsistenz", "ACID, lokal", "eventual / Saga"),
]
ry = Inches(5.5)
rh = Inches(0.33)
chip_w = Inches(1.95)
for i, (dim, mono, ms) in enumerate(rows):
y = ry + rh * i
chip = shp(MSO_SHAPE.ROUNDED_RECTANGLE, Inches(6.65) - chip_w / 2, y, chip_w, Inches(0.28),
line=LINEC, lw=Pt(0.75))
chip.fill.background()
boxtext(chip, dim, size=11, color=LIGHT, bold=True)
txt(Inches(2.5), y - Inches(0.02), Inches(3.1), Inches(0.32), mono,
size=12, color=WHITE, align=PP_ALIGN.RIGHT)
txt(Inches(7.72), y - Inches(0.02), Inches(3.1), Inches(0.32), ms,
size=12, color=WHITE, align=PP_ALIGN.LEFT)
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie3b.pptx")
prs.save(out)
print("saved", out)
+33 -42
View File
@@ -1,36 +1,33 @@
#!/usr/bin/env python3
"""Folie 4 Eventstream als Quelle; Aussagen links, Lupen rechts, Strecke unten."""
"""Folie 4 Eventstream als Quelle; Aussagen links, Lupen rechts, Strecke unten
(adesso-Styling)."""
import os
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, RECF, F, FC,
paint_background, chrome)
INK = RGBColor(0x2A, 0x2F, 0x3A)
NAVY = RGBColor(0x1F, 0x3A, 0x5F)
ACCENT = RGBColor(0xC0, 0x49, 0x2F)
TEAL = RGBColor(0x2F, 0x8F, 0x83)
AMBER = RGBColor(0xC8, 0x8A, 0x3A)
MUTE = RGBColor(0x8A, 0x93, 0xA0)
GLASS = RGBColor(0xF2, 0xF5, 0xF8)
BELT = RGBColor(0xD7, 0xDC, 0xE2)
DARK = RGBColor(0x33, 0x39, 0x44)
LINEC = RGBColor(0xC3, 0xC9, 0xD1)
THIN = RGBColor(0xDD, 0xE2, 0xE8)
STREAM = RGBColor(0x24, 0x37, 0x52)
BG = RGBColor(0xFF, 0xFF, 0xFF)
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
F = "Calibri"
# Rollen-Mapping auf die adesso-Palette
NAVY = INK # dunkle Füllungen (Lupe, Maschine)
ACCENT = CORAL
AMBER = GREEN
GLASS = RECF
BELT = RECF
DARK = INK
LINEC = LIGHT
THIN = LIGHT
STREAM = INK
MID = RGBColor(0x34, 0x4E, 0x70)
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
SW, SH = prs.slide_width, prs.slide_height
s = prs.slides.add_slide(prs.slide_layouts[6])
bgr = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, SW, SH)
bgr.fill.solid(); bgr.fill.fore_color.rgb = BG; bgr.line.fill.background()
bgr.shadow.inherit = False
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0):
@@ -44,25 +41,21 @@ def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0):
return sh
def txt(x, y, w, h, t, size=16, color=INK, bold=False, italic=False,
align=PP_ALIGN.LEFT, spc=None):
def txt(x, y, w, h, t, size=16, color=WHITE, bold=False, italic=False,
align=PP_ALIGN.LEFT, spc=None, font=F):
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
tf.word_wrap = True; tf.vertical_anchor = MSO_ANCHOR.MIDDLE
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
p = tf.paragraphs[0]; p.alignment = align
r = p.add_run(); r.text = t
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
r.font.name = F; r.font.color.rgb = color
r.font.name = font; r.font.color.rgb = color
if spc: r.font._rPr.set('spc', str(spc))
return tb
# ---- Kopf (ganz oben) ------------------------------------------------------
txt(Inches(0.95), Inches(0.32), Inches(8), Inches(0.35), "MODELL",
size=12.5, color=ACCENT, bold=True, spc=240)
txt(Inches(0.95), Inches(0.62), Inches(11), Inches(0.85), "Zustand oder Ereignis",
size=31, color=NAVY, bold=True)
shp(MSO_SHAPE.RECTANGLE, Inches(0.95), Inches(1.34), Inches(0.6), Pt(4), fill=ACCENT)
paint_background(s, SW, SH)
chrome(s, "Zustand oder Ereignis", 5)
x0, x1 = Inches(1.0), Inches(12.33)
beltw = x1 - x0
@@ -77,25 +70,23 @@ cy = Inches(1.95)
for i, c in enumerate(claims):
y = cy + Inches(0.6) * i
shp(MSO_SHAPE.RECTANGLE, Inches(0.95), y + Inches(0.1), Inches(0.14), Inches(0.14), fill=ACCENT)
bold = (i == 0)
txt(Inches(1.28), y, Inches(4.6), Inches(0.45), c,
size=16.5, color=INK, bold=bold)
txt(Inches(1.28), y, Inches(4.6), Inches(0.45), c, size=16.5, color=WHITE, bold=(i == 0))
# ===========================================================================
# LUPEN (Projektionen) nach rechts gerückt
# LUPEN (Projektionen)
# ===========================================================================
def lupe(cx, label, label_w):
cy = Inches(2.45)
cyy = Inches(2.45)
d = Inches(0.9)
shp(MSO_SHAPE.OVAL, cx - d / 2, cy - d / 2, d, d, fill=WHITE, line=NAVY, lw=Pt(4))
shp(MSO_SHAPE.OVAL, cx - d / 2 + Inches(0.13), cy - d / 2 + Inches(0.12),
Inches(0.17), Inches(0.13), fill=RGBColor(0xED,0xF1,0xF5))
shp(MSO_SHAPE.OVAL, cx - d / 2, cyy - d / 2, d, d, fill=WHITE, line=NAVY, lw=Pt(4))
shp(MSO_SHAPE.OVAL, cx - d / 2 + Inches(0.13), cyy - d / 2 + Inches(0.12),
Inches(0.17), Inches(0.13), fill=RECF)
hw, hh = Inches(0.48), Inches(0.15)
hcx, hcy = cx + d * 0.52, cy + d * 0.52
hcx, hcy = cx + d * 0.52, cyy + d * 0.52
shp(MSO_SHAPE.ROUNDED_RECTANGLE, hcx - hw / 2, hcy - hh / 2, hw, hh, fill=NAVY, rot=45)
txt(cx - label_w / 2, cy + d / 2 + Inches(0.16), label_w, Inches(0.6),
label, size=14, color=NAVY, bold=True, align=PP_ALIGN.CENTER)
return cy + d / 2
txt(cx - label_w / 2, cyy + d / 2 + Inches(0.16), label_w, Inches(0.6),
label, size=14, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
return cyy + d / 2
lupes = [
@@ -133,7 +124,7 @@ mx, mw = Inches(5.45), Inches(2.45)
my, mh = Inches(5.2), Inches(1.5)
shp(MSO_SHAPE.ROUNDED_RECTANGLE, mx, my, mw, mh, fill=NAVY)
shp(MSO_SHAPE.ROUNDED_RECTANGLE, mx + Inches(0.3), my + Inches(0.22),
mw - Inches(0.6), Inches(0.32), fill=RGBColor(0x34,0x4E,0x70))
mw - Inches(0.6), Inches(0.32), fill=MID)
shp(MSO_SHAPE.OVAL, mx + Inches(0.35), my + Inches(0.74), Inches(0.15), Inches(0.15), fill=TEAL)
shp(MSO_SHAPE.OVAL, mx + Inches(0.6), my + Inches(0.74), Inches(0.15), Inches(0.15), fill=AMBER)
shp(MSO_SHAPE.RECTANGLE, mx - Inches(0.02), belt_top - Inches(0.02),
@@ -165,6 +156,6 @@ for xv in pre_x + post_x:
shp(MSO_SHAPE.OVAL, Inches(xv) - Inches(0.05), acx - Inches(0.05),
Inches(0.1), Inches(0.1), fill=AMBER)
out = "/home/marcuh/claude-projects/limbach/Folie4.pptx"
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie4.pptx")
prs.save(out)
print("saved", out)
+2
View File
@@ -1 +1,3 @@
- [Limbach Workshop / Outline](limbach-workshop-outline.md) — Wissensaufbau in Outline für Workshop 15./16.06.2026
- [adesso Styling](adesso-styling.md) — Corporate-Template-Quelle & Design-Tokens für Folien 24 (adesso_style.py)
- [Verbotene Wörter](verbotene-woerter.md) — „Pointe", „der Hit", „der Clou" & reißerische Wörter nie verwenden
+18
View File
@@ -0,0 +1,18 @@
---
name: adesso-styling
description: Corporate-Template-Quelle und Design-Tokens für das adesso-Styling der Workshop-Folien
metadata:
node_type: memory
type: reference
originSessionId: 38920718-90c7-440b-acfe-8a06dc15263b
---
Die Workshop-Folien (Folie 24) wurden auf das **adesso-Corporate-Template** umgestylt.
- **Referenz-Deck:** `/Users/marcus.hinz/Documents/schnzz.pptx` (adesso-Masterdeck, 96 Folien; LibreOffice exportiert nur die ~19 sichtbaren).
- **Design-Tokens** (extrahiert aus dem Theme): Fonts **Fira Sans Condensed** (Titel) / **Fira Sans** (Body); Palette Blau `#006EC7`, Purpur `#461EBE`, Grün `#76C800`, Teal `#28DCAA`, Coral `#FF9868`, Pink `#F566BA`, Taupe `#887D75`.
- **Look:** Teal→Blau-Verlauf, weiße Shapes + Text, Coral-Akzente; Header = Pill-Marker + Titel; schlanke Fußzeile = Seitenzahl + „adesso".
Implementiert im geteilten Modul `adesso_style.py` (von `folie2/3/4.py` importiert). Logo wird als Text „adesso" gesetzt (echtes Asset `image2.svg` im Template ist weiß-auf-weiß ohne Alpha → nicht direkt nutzbar).
Siehe [[limbach-workshop-outline]].
+17
View File
@@ -0,0 +1,17 @@
---
name: verbotene-woerter
description: Wörter, die in Folien/Texten für den User niemals verwendet werden dürfen
metadata:
type: feedback
---
Reißerische / werbliche „Aha"-Wörter sind verboten weder in Folieninhalten noch in der Konversation. Konkret untersagt:
- **„Pointe"**
- **„der Hit"**
- **„der Clou"**
- sinngleiche Effekthascherei (z. B. „der Knaller", „das Highlight", „der Wow-Effekt", „die Sensation")
**Why:** Ausdrückliche, mit Nachdruck formulierte Vorgabe des Users; passt nicht zum sachlichen Ton.
**How to apply:** Komplett vermeiden. Stattdessen nüchtern: „Kernaussage", „das Entscheidende", „Fazit", „der zentrale Vorteil", „der wesentliche Unterschied". Liste bei weiteren Hinweisen ergänzen.
+3 -2
View File
@@ -2,13 +2,14 @@
"""Fügt Folie2, Folie3, Folie4 zu einer Datei zusammen (Reihenfolge 2, 3, 4)."""
import copy
import os
from pptx import Presentation
base = "/home/marcuh/claude-projects/limbach/"
base = os.path.dirname(os.path.abspath(__file__)) + "/"
dst = Presentation(base + "Folie2.pptx") # Seite 1 = Folie 2
blank = dst.slide_layouts[6]
for fname in ("Folie3.pptx", "Folie4.pptx"): # Seiten 2 und 3
for fname in ("Folie3.pptx", "Folie3b.pptx", "Folie4.pptx"): # Seiten 2, 3, 4, 5
src = Presentation(base + fname)
new_slide = dst.slides.add_slide(blank)
for shape in src.slides[0].shapes: