From 957dfef98d52f4acda2d88fd2458463b6eb1c57c Mon Sep 17 00:00:00 2001 From: AljGe Date: Fri, 17 Oct 2025 13:18:00 +0200 Subject: [PATCH] Refactor demo and template files: removed horizontal logo demo, added responsive sizing and spacing functions for text elements, and improved logo placement logic for vertical layouts. --- demo.typ | 13 ---- template.typ | 165 ++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 137 insertions(+), 41 deletions(-) diff --git a/demo.typ b/demo.typ index 66b2d22..61ddf23 100644 --- a/demo.typ +++ b/demo.typ @@ -41,19 +41,6 @@ about: [This is a simple event with just one logo.] ) -// Demo 4: Vier Logos in horizontalem Layout (Gitter) -#sharepic( - logos: ( - (path: "tux.svg", height: 3cm), - (path: "connection.png", height: 3cm, rotation: -10deg), - (path: "kew.jpg", height: 3cm, rotation: 10deg), - (path: "tux.svg", height: 3cm, rotation: -5deg) - ), - layout: "horizontal", - title: [Four Logo Event], - about: [This demonstrates how four logos are arranged in a grid pattern in horizontal layout.] -) - // Demo 5: Vertikales layout mit benutzerdefinierter Positionierung #sharepic( logos: ( diff --git a/template.typ b/template.typ index abe6393..4b420f4 100644 --- a/template.typ +++ b/template.typ @@ -7,10 +7,21 @@ body-font: "DejaVu Sans", border-radius: 0.8cm, border-stroke: 4pt, + // Fixed sizes (fallback if responsive is disabled) title-size: 20pt, label-size: 12pt, body-size: 12pt, info-text-size: 12pt, + // Responsive sizing configuration + title-size-max: 28pt, + title-size-min: 14pt, + title-base-length: 45, // Character count baseline + body-size-max: 14pt, + body-size-min: 9pt, + body-base-length: 200, // Character count baseline + info-size-max: 11pt, + info-size-min: 9pt, + info-base-length: 60, // Character count baseline ) // Default logo configuration @@ -18,7 +29,7 @@ path: none, height: 4cm, fit: "contain", - rotation: 0deg, + rotation: 10deg, offset: (x: 0cm, y: 0cm), pin-position: none, // "top-left", "top-center", "top-right", etc. ) @@ -68,51 +79,147 @@ place-logo(logos.at(0), top + left, dx: 1.5cm, dy: 0.7cm) place-logo(logos.at(1), top + center, dy: 0.7cm) place-logo(logos.at(2), top + right, dx: -1.5cm, dy: 0.7cm) - } else { - // 4+ logos - anordnen in Gitter - let cols = calc.min(2, logos.len()) - let rows = calc.ceil(logos.len() / cols) - for (i, logo) in logos.enumerate() { - let row = calc.floor(i / cols) - let col = calc.rem(i, cols) - let x = -2.5cm + col * 5cm - let y = 0.5cm + row * 2.2cm - place-logo(logo, top + left, dx: x, dy: y) - } } } else if layout == "vertical" { - // Logos auf der rechten Seite positioniert, vertikal gestapelt + // Logos auf der rechten Seite positioniert, vertikal gestapelt und zentral angeordnet + let card-height = 14cm + let logo-height = 4cm // Standard logo height + if logos.len() == 1 { - place-logo(logos.first(), top + right, dx: -1cm, dy: 0.7cm) + // Single logo: centered vertically + let dy = (card-height - logo-height) / 2 + place-logo(logos.first(), top + right, dx: -1cm, dy: dy) } else if logos.len() == 2 { - place-logo(logos.at(0), top + right, dx: -1cm, dy: 0.7cm) - place-logo(logos.at(1), top + right, dx: -1cm, dy: 4.2cm) + // Two logos: vertically spaced around center + let total-height = 2 * logo-height + let start-dy = (card-height - total-height) / 2 + place-logo(logos.at(0), top + right, dx: -1cm, dy: start-dy) + place-logo(logos.at(1), top + right, dx: -1cm, dy: start-dy + logo-height) } else { - // 3+ logos: vertikal auf der rechten Seite mit leichtem Offset gestapelt + // 3+ logos: evenly distributed vertically around center + let total-height = logos.len() * logo-height + let start-dy = (card-height - total-height) / 2 for (i, logo) in logos.enumerate() { - let dy = 0.7cm + i * 3.5cm + let dy = start-dy + i * logo-height place-logo(logo, top + right, dx: -1cm, dy: dy) } } } } +// Hilfsfunktion um responsive Schriftgröße zu berechnen basierend auf Textlänge +#let calculate-responsive-size(text-content, max-size: 28pt, min-size: 14pt, base-length: 50) = { + // Zähle Zeichen in Text + let text-length = if type(text-content) == str { + text-content.len() + } else if type(text-content) == content { + // Für Content-Blöcke: Schätzung der Länge + repr(text-content).len() + } else { + 0 + } + + // Berechne Reduktionsfaktor + let ratio = if text-length > base-length { + (base-length / text-length) + } else { + 1.0 + } + + // Skaliere die Größe, halte sie in Grenzen + let range = max-size - min-size + let scaled = min-size + range * ratio + + // Stelle sicher, dass die Größe in Grenzen bleibt + if scaled > max-size { + max-size + } else if scaled < min-size { + min-size + } else { + scaled + } +} + +// Hilfsfunktion um responsive Abstände basierend auf Textmenge zu berechnen +#let calculate-responsive-spacing(about-content, max-spacing: 1.2em, min-spacing: 0.6em, base-length: 200) = { + let text-length = if type(about-content) == str { + about-content.len() + } else if type(about-content) == content { + repr(about-content).len() + } else { + 0 + } + + // Reduziere Abstand wenn viel Text vorhanden + let ratio = if text-length > base-length { + (base-length / text-length) + } else { + 1.0 + } + + let range = max-spacing - min-spacing + let scaled = min-spacing + range * ratio + + if scaled > max-spacing { + max-spacing + } else if scaled < min-spacing { + min-spacing + } else { + scaled + } +} + // Hilfsfunktion um den Inhalt zu arrangieren #let arrange-content(title: [], when: [], where: [], about: [], layout: "horizontal", current-theme: theme) = { let left-padding = if layout == "vertical" { 1.5cm } else { 1.5cm } let right-padding = if layout == "vertical" { 5cm } else { 1.5cm } let top-padding = if layout == "vertical" { 0.8cm } else { 5.5cm } + // Berechne responsive Schriftgrößen + let responsive-title-size = calculate-responsive-size( + title, + max-size: current-theme.title-size-max, + min-size: current-theme.title-size-min, + base-length: current-theme.title-base-length + ) + + let responsive-body-size = calculate-responsive-size( + about, + max-size: current-theme.body-size-max, + min-size: current-theme.body-size-min, + base-length: current-theme.body-base-length + ) + + let responsive-info-size = calculate-responsive-size( + when + where, + max-size: current-theme.info-size-max, + min-size: current-theme.info-size-min, + base-length: current-theme.info-base-length + ) + + // Berechne responsive Abstände + let responsive-spacing = calculate-responsive-spacing( + about, + max-spacing: 1.2em, + min-spacing: 0.5em, + base-length: current-theme.body-base-length + ) + + // Berechne maximale Höhe für Beschreibungstext basierend auf verfügbarem Platz + // Card: 14cm x 14cm, Padding: 1.5cm L+R, 1.5cm B, 5.5cm T (horizontal) + // Ungefähre verfügbare Höhe: 14cm - 5.5cm - 1.5cm (Title/Info space) - 1.5cm (padding) = 5.5cm + let max-about-height = 5.5cm + pad(top: top-padding, bottom: 1.5cm, left: left-padding, right: right-padding)[ #stack( dir: ttb, - spacing: 1em, - // Title + spacing: responsive-spacing, + // Title mit responsiver Größe if title != [] { - text(size: current-theme.title-size, weight: "bold", font: current-theme.heading-font, title) + text(size: responsive-title-size, weight: "bold", font: current-theme.heading-font, title) }, - // Info-Block für wann/wo + // Info-Block für wann/wo mit responsiver Größe if when != [] or where != [] { block( inset: 0.8em, @@ -127,7 +234,7 @@ dir: ltr, spacing: 0.5em, align(center + horizon, emoji.calendar), - text(size: current-theme.info-text-size, when), + text(size: responsive-info-size, when), )) }, if where != [] { @@ -135,19 +242,21 @@ dir: ltr, spacing: 0.5em, align(center + horizon, emoji.pin), - text(size: current-theme.info-text-size, where), + text(size: responsive-info-size, where), )) }, ), ) }, - // Beschreibungstext + // Beschreibungstext mit responsiver Größe und maximaler Höhe if about != [] { let about-align = if layout == "vertical" { left } else { center } - block( - spacing: 0.1em, - align(about-align, text(size: current-theme.body-size, about)) + box( + height: max-about-height, + width: 100%, + clip: true, + align(about-align, text(size: responsive-body-size, about)) ) } )