diff --git a/packages/preview/sgh-presentation/0.1.2/LICENSE b/packages/preview/sgh-presentation/0.1.2/LICENSE new file mode 100644 index 0000000000..d01ff80e12 --- /dev/null +++ b/packages/preview/sgh-presentation/0.1.2/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Piotr Kuszewski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/packages/preview/sgh-presentation/0.1.2/README.md b/packages/preview/sgh-presentation/0.1.2/README.md new file mode 100644 index 0000000000..033ddb4d51 --- /dev/null +++ b/packages/preview/sgh-presentation/0.1.2/README.md @@ -0,0 +1,69 @@ +# sgh-presentation + +A presentation theme for [Touying](https://typst.app/universe/package/touying) +following the visual identity of the SGH Warsaw School of Economics (Szkoła +Główna Handlowa w Warszawie). The theme is bilingual — the SGH logo switches +between Polish and English depending on the document language (`pl` / `en`). + +The standard font for SGH presentations is Lato (a free font developed in Poland +by Łukasz Dziedzic, available at ). If Lato is not +installed, Typst falls back to a default font. On the Typst web app the font is +already available. + +The full manual, a complete example presentation, and the matching SGH thesis +template are available in the project repository: +. + +![Title slide of the example presentation produced with the theme](thumbnail.png) + +## Usage + +The theme builds on Touying, so import both packages: + +```typst +#import "@preview/touying:0.7.4": * +#import "@preview/sgh-presentation:0.1.2": * + +#set text(lang: "pl") // the SGH logo follows the language: "pl" or "en" + +#show: sgh-presentation-theme.with( + config-info( + title: [Prezentacja], + author: [Ijon Tichy], + date: [Marzec 2026], + ), + // footer: [custom footer], + // footer-progress: true, + // aspect-ratio: "4-3", +) + +#title-slide() + +== A simple slide + +Some text on the slide. + += Section + +== Another slide + +#focus-slide[Wake up!] +``` + +## Available functions + +- `sgh-presentation-theme(...)` — the main theme (used with + `#show: sgh-presentation-theme.with(...)`). Options include `aspect-ratio`, + `align`, `header`, `header-right`, `footer`, `footer-right` and + `footer-progress`. +- `title-slide(...)` — the title slide (SGH logo on the brand background). +- `slide(...)` — a regular content slide. +- `new-section-slide(...)` — a section-divider slide. +- `focus-slide[...]` — a full-bleed slide used to draw attention. + +Slide structure follows Touying conventions: level-1 headings (`=`) start new +sections and level-2 headings (`==`) start new slides. + +## License + +MIT — see the [LICENSE](LICENSE) file. diff --git a/packages/preview/sgh-presentation/0.1.2/sgh-presentation.typ b/packages/preview/sgh-presentation/0.1.2/sgh-presentation.typ new file mode 100644 index 0000000000..fc0cc0e665 --- /dev/null +++ b/packages/preview/sgh-presentation/0.1.2/sgh-presentation.typ @@ -0,0 +1,664 @@ +// This theme is inspired by Metropolis theme originally shipped with Touying 0.6.1 +// The Touying Metropolis theme is inspired by https://github.com/matze/mtheme +// The origin code was written by https://github.com/Enivex + +#import "@preview/touying:0.7.4": * + +#let sgh-green = rgb("#007481") +#let sgh-blue = rgb("#00b5e2") +#let sgh-text = rgb("#23373b") + +#let sgh-logotyp = ```xml + + + + + + + + + + + +```.text + +#let sgh-kwadrat-en = ```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +```.text + +#let sgh-kwadrat-pl = ```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +```.text + +#let loc-pl-en(pl, en) = context { + if text.lang == "en" { en } else { pl } +} + +/// Domyślna funkcja slajdu dla prezentacji. +/// - title (string): Tytuł slajdu. Domyślnie `auto`. +/// - config (dictionary): Konfiguracja slajdu. Możesz użyć `config-xxx` +/// aby ustawić konfigurację slajdu. Dla kilku konfiguracji możesz użyć +/// `utils.merge-dicts` aby je połączyć. +/// - repeat (int, string): Liczba podslajdów. Domyślnie `auto`, co oznacza, +/// że touying automatycznie obliczy liczbę podslajdów. Argument `repeat` +/// jest konieczny gdy używasz kodu podobnego do `#slide(repeat: 3, self => [ .. ])` aby utworzyć slajd. Style `uncover` i `only` oparte na odwołaniach nie mogą być automatycznie wykryte przez touying. +/// - setting (function): Ustawienia slajdu. Możesz go używać aby dodać +/// reguły set/show dla slajdu. +/// - composer (function, array): Komponent composer slajdu. Możesz go używać aby ustawić +/// układ slajdu. Na przykład, `#slide(composer: (1fr, 2fr, 1fr))[A][B][C]` +/// aby podzielić slajd na trzy części. Pierwsza i ostatnia część zajmą +/// 1/4 slajdu, a druga część zajmie 1/2 slajdu. Jeśli przekażesz +/// wartość niebędącą funkcją jak `(1fr, 2fr, 1fr)`, zostanie przyjęta jako pierwszy +/// argument funkcji `components.side-by-side`. +/// Funkcja `components.side-by-side` jest prostym opakowaniem funkcji `grid`. +/// Oznacza to, że możesz użyć `grid.cell(colspan: 2, ..)` aby sprawić, że komórka zajmie +/// 2 kolumny. +/// Na przykład, `#slide(composer: 2)[A][B][#grid.cell(colspan: 2)[Footer]]` +/// sprawi, że komórka `Footer` zajmie 2 kolumny. +/// +/// Jeśli chcesz dostosować układ, możesz przekazać funkcję do argumentu `composer`. +/// Funkcja powinna otrzymać zawartość slajdu i zwrócić +/// zawartość slajdu, na przykład `#slide(composer: grid.with(columns: 2))[A][B]`. +/// +/// - bodies (array): Zawartość slajdu. Możesz wywoływać funkcję `slide` +/// z składnią `#slide[A][B][C]` aby utworzyć slajd. +// -> none +#let slide( + title: auto, + align: auto, + config: (:), + repeat: auto, + setting: body => body, + composer: auto, + ..bodies, +) = touying-slide-wrapper(self => { + if align != auto { + self.store.align = align + } + let header(self) = { + set std.align(top) + show: components.cell.with(fill: self.colors.primary-lightest, inset: 1em) + set std.align(horizon) + set text(fill: sgh-green, weight: 900, size: 1.5em) + components.left-and-right( + { + if title != auto { + utils.fit-to-width(grow: false, 100%, title) + } else { + utils.call-or-display(self, self.store.header) + } + }, + utils.call-or-display(self, self.store.header-right), + ) + } + let footer(self) = { + set std.align(bottom) + set text(size: 0.8em) + pad( + .5em, + components.left-and-right( + //image(bytes(sgh-logotyp), format: "svg", height: 1em), + text(fill: self.colors.neutral-darkest.lighten(40%), utils.call-or-display(self, self.store.footer)), + text(fill: self.colors.neutral-darkest, utils.call-or-display(self, self.store.footer-right)), + ), + ) + if self.store.footer-progress { + place(bottom, components.progress-bar(height: 2pt, self.colors.primary, self.colors.primary-light)) + } + } + let self = utils.merge-dicts( + self, + config-page( + fill: self.colors.neutral-lightest, + header: header, + footer: footer, + ), + ) + let new-setting = body => { + show: std.align.with(self.store.align) + set text(fill: self.colors.neutral-darkest) + show: setting + body + } + touying-slide(self: self, config: config, repeat: repeat, setting: new-setting, composer: composer, ..bodies) +}) + +/// Strona tytułowa dla prezentacji. Powinieneś zaktualizować informacje w +/// funkcji `config-info`. Możesz również przekazać informacje bezpośrednio do +/// funkcji `title-slide`. +/// +/// Przykład: +/// ```typst +/// #show: sgh-presentation-theme.with( +/// config-info( +/// title: [Tytuł], +/// author: [Autor], +/// institution: [Instytucja], +/// logo: emoji.city, +/// ), +/// footer: [Moja stopka], +/// footer-progress: true, +/// aspect-ratio: "4-3", +/// ) +/// +/// #title-slide(subtitle: [Podtytuł], extra: [Dodatkowe informacje]) +/// ``` +/// - config (dictionary): Konfiguracja slajdu. Możesz używać `config-xxx` do +/// ustawienia konfiguracji slajdu. Dla kilku konfiguracji możesz użyć +/// `utils.merge-dicts` do ich połączenia. +/// - extra (string, none): Dodatkowe informacje, które chcesz wyświetlić na stronie tytułowej. +/// -> none +#let title-slide( + config: (:), + extra: none, + ..args, +) = touying-slide-wrapper(self => { + self = utils.merge-dicts( + self, + config, + config-common(freeze-slide-counter: true), + config-page(fill: sgh-green), + ) + let info = self.info + args.named() + let body = { + loc-pl-en(image(bytes(sgh-kwadrat-pl), format: "svg", width: 3cm), image(bytes(sgh-kwadrat-en), format: "svg", width: 3cm)) + set text(fill: self.colors.neutral-lightest) + set std.align(horizon) + block( + width: 100%, + inset: 0.8em, + { + components.left-and-right( + { + text(size: 1.5em, text(weight: "bold", info.title)) + if info.subtitle != none { + linebreak() + text(size: 1em, info.subtitle) + } + }, + text(2em, utils.call-or-display(self, info.logo)), + ) + set text(size: 1em) + if info.author != none { + block(spacing: 1em, info.author) + } + if info.date != none { + block(spacing: 1em, utils.display-info-date(self)) + } + set text(size: 1em) + if info.institution != none { + block(spacing: 1em, info.institution) + } + if extra != none { + block(spacing: 1em, extra) + } + }, + ) + } + touying-slide(self: self, body) +}) + + +/// Slajd nowego rozdziału dla prezentacji. Możesz go zaktualizować, zmieniając argument `new-section-slide-fn` funkcji `config-common`. +/// +///Przykład: `config-common(new-section-slide-fn: new-section-slide.with(numbered: false))` +/// +/// - config (dictionary): Konfiguracja slajdu. Możesz użyć `config-xxx` do ustawienia konfiguracji slajdu. Dla kilku konfiguracji możesz użyć `utils.merge-dicts` aby je połączyć. +/// - level (int): Poziom nagłówka. +/// - numbered (boolean): Określa, czy nagłówek jest numerowany. +/// - body (auto): Zawartość rozdziału. Będzie przekazana automatycznie przez touying. +/// -> none +#let new-section-slide(config: (:), level: 1, numbered: true, body) = touying-slide-wrapper(self => { + let slide-body = { + set std.align(horizon) + show: pad.with(20%) + set text(size: 1.5em, weight: "bold", hyphenate: false) + stack( + dir: ttb, + spacing: 1em, + text(self.colors.neutral-darkest, utils.display-current-heading(level: level, numbered: numbered, style: auto)), + block( + height: 2pt, + width: 100%, + spacing: 0pt, + components.progress-bar(height: 2pt, self.colors.primary, self.colors.primary-light), + ), + ) + text(self.colors.neutral-dark, body) + } + self = utils.merge-dicts( + self, + config-page(fill: self.colors.neutral-lightest), + ) + touying-slide(self: self, config: config, slide-body) +}) + +#let focus-slide(config: (:), align: horizon + center, body) = touying-slide-wrapper(self => { + self = utils.merge-dicts( + self, + config-common(freeze-slide-counter: true), + config-page(fill: self.colors.neutral-dark, margin: 1.5em), + ) + set text(fill: self.colors.neutral-lightest, size: 1.5em, weight: "bold") + touying-slide(self: self, config: config, std.align(align, body)) +}) + +/// Parametry motywu prezentacji: +/// - aspect-ratio (string): Współczynnik proporcji slajdów. Domyślnie `16-9`. +/// - align (alignment): Wyrównanie zawartości. Domyślnie `horizon`. +/// - header (content, function): Nagłówek slajdu. Domyślnie `self => utils.display-current-heading(setting: utils.fit-to-width.with(grow: false, 100%), depth: self.slide-level)`. +/// - header-right (content, function): Prawa część nagłówka. +/// - footer (content, function): Stopka slajdu. +/// - footer-right (content, function): Prawa część stopki. Domyślnie `context utils.slide-counter.display() + " / " + utils.last-slide-number`. +/// - footer-progress (boolean): Czy wyświetlać pasek postępu w stopce. Domyślnie `false`. +/// -> none +#let sgh-presentation-theme( + /// Współczynnik proporcji slajdów. Domyślnie `16-9`. -> str + aspect-ratio: "16-9", + /// Wyrównanie zawartości. Domyślnie `horizon`. -> alignment + align: horizon, + /// Nagłówek slajdu. Domyślnie ustawiony na automatyczne dopasowanie tytułu do szerokości slajdu. -> content + header: self => utils.display-current-heading( + setting: utils.fit-to-width.with(grow: false, 100%), + depth: self.slide-level, + ), + /// Dodatkowe informacje po prawej stronie nagłówka. -> content + header-right: none, + /// Stopka slajdu. Domyślnie ustawiona na logo SGH. -> content + footer: image(bytes(sgh-logotyp), format: "svg", height: 1em), + /// Prawa strona stopki slajdu. Domyślnie ustawiona na nr slajdu / liczba slajdów. -> content + footer-right: context utils.slide-counter.display() + " / " + utils.last-slide-number, + /// Widoczność paska postępu na dole slajdu. -> boolean + footer-progress: false, + ..args, + body, +) = { + set text(size: 20pt) + // Fonty prezentacji. W przypadku braku fontu Lato używany jest font domyślny. + show math.equation: set text(font: "New Computer Modern Math") + show text: set text(font: "Lato", fallback: true) + // Referencing + set ref(supplement: none) + show ref: it => { + let el = it.element + if el != none and el.func() == math.equation { + [(#it)] + } else { + it + } + } + // Parametry tekstu + set strong(delta: 200) + set par(justify: true) + show math.equation: it => { + // Wszsytkie przecinki są typu "normal" (bez cienkiej spacji) + show ",": math.class("normal", ",") + // ", " (przecinek + spacja) → wstawia przecinek jako klasę "punctuation" i usuwa spację + // (klasa "punctuation" wstawia cienką spację domyślnie) + show regex(",\\s"): math.class("punctuation", ",") + it + } + // Style level 3 headings + show heading.where(level: 3): set text(fill: sgh-green) + // Markery w listach nienumerowanych + set list( + marker: ( + text(fill: sgh-green, sym.square.filled), + text(weight: "bold", fill: sgh-green, sym.quote.chevron.r.double), + text(weight: "bold", fill: sgh-green, sym.dash.en), + ) + ) + // Formatowanie tabel, pogrubiony nagłówek i naprzemienne cieniowanie wierszy + show table.cell.where(y: 0): set text(weight: "bold", fill: sgh-green) + let frame(stroke) = (x, y) => ( + left: 0pt, + right: 0pt, + top: if y == 0 { stroke + 1.5pt} else if y == 1 { stroke + 1pt} else { 0pt }, + bottom: stroke + 1.5pt, + ) + set table( + fill: (_, y) => if calc.odd(y) { sgh-green.lighten(90%) }, + stroke: frame(sgh-text), + ) + + show: touying-slides.with( + config-page( + paper: "presentation-" + aspect-ratio, + header-ascent: 0%, + footer-descent: 30%, + margin: (top: 3em, bottom: 1.5em, x: 3em), + ), + config-common( + slide-fn: slide, + new-section-slide-fn: new-section-slide, + ), + config-methods( + alert: utils.alert-with-primary-color, + ), + config-colors( + primary: sgh-green, // aktywna część paska postępu, sgh-green + primary-light: rgb("#dddddd"), // tło paska postępu, gray + secondary: sgh-green, // tło, green + neutral-lightest: rgb("#ffffff"), // tło slajdu, białe + neutral-dark: sgh-green, // tło slajdu "końcowego", sgh-green + neutral-darkest: sgh-text, // kolor głównego tesktu, ciemy szaro-zielony + ), + // zapamiętanie zmiennych do przyszłego wykorzystania + config-store( + align: align, + header: header, + header-right: header-right, + footer: footer, + footer-right: footer-right, + footer-progress: footer-progress, + ), + ..args, + ) + + body +} \ No newline at end of file diff --git a/packages/preview/sgh-presentation/0.1.2/thumbnail.png b/packages/preview/sgh-presentation/0.1.2/thumbnail.png new file mode 100644 index 0000000000..583263a59f Binary files /dev/null and b/packages/preview/sgh-presentation/0.1.2/thumbnail.png differ diff --git a/packages/preview/sgh-presentation/0.1.2/typst.toml b/packages/preview/sgh-presentation/0.1.2/typst.toml new file mode 100644 index 0000000000..1a70d954b3 --- /dev/null +++ b/packages/preview/sgh-presentation/0.1.2/typst.toml @@ -0,0 +1,13 @@ +[package] +name = "sgh-presentation" +version = "0.1.2" +entrypoint = "sgh-presentation.typ" +authors = ["Piotr Kuszewski "] +license = "MIT" +description = "A bilingual (Polish and English) Touying presentation theme following the visual identity of the SGH Warsaw School of Economics." +repository = "https://github.com/piotr-m-kuszewski/Szablony_Typst_SGH" +keywords = ["presentation", "slides", "touying", "SGH", "Warsaw School of Economics"] +categories = ["presentation"] +disciplines = ["economics"] +compiler = "0.13.0" +exclude = ["thumbnail.png"]