// ========================================================= // style.typ – Szablon Pracy Dyplomowej // Wydział Informatyki, ZUT w Szczecinie // Typst 0.12+ // ========================================================= // ╔═══════════════════════════════════════════════════════╗ // ║ 1. KOLORY ║ // ╚═══════════════════════════════════════════════════════╝ #let blue-wi = cmyk(60%, 20%, 0%, 0%) // blueWI – jasny niebieski WI #let blue-zut = cmyk(100%, 75%, 0%, 20%) // blueZUT – granatowy ZUT #let gray-zut = cmyk(0%, 0%, 0%, 40%) // grayZUT – szary ZUT // Pochodne (odpowiedniki blueWI!20, blueZUT!60 itp.) #let blue-wi-20 = blue-wi.lighten(80%) #let blue-zut-60 = blue-zut.lighten(40%) #let gray-zut-10 = gray-zut.lighten(90%) // Kolory kodu źródłowego #let code-green = rgb(0, 154, 0) #let code-gray = rgb(128, 128, 128) #let code-violet = rgb(148, 0, 211) #let theorem(title: none, body) = block( width: 100%, fill: luma(97%), stroke: (top: 1.2pt + blue-zut, bottom: 1.2pt + blue-zut, left: 1.2pt + blue-zut, right: 1.2pt + blue-zut), inset: 8pt, above: 8pt, below: 8pt, )[ #text(size: 10pt, weight: "bold", font: "Fira Sans", fill: blue-zut)[ Twierdzenie#if title != none [ — #title] ] #parbreak() #body ] /// Definicja – lewa kreska 2pt blueZUT (dBox) #let definition(title: none, body) = block( width: 100%, stroke: (left: 2pt + blue-zut), inset: (left: 10pt, right: 8pt, top: 4pt, bottom: 4pt), above: 8pt, below: 8pt, )[ #text(size: 10pt, weight: "bold", font: "Fira Sans")[ Definicja#if title != none [ — #title] ] #parbreak() #body ] #let example(title: none, body) = block( above: 6pt, below: 6pt, )[ #text(size: 10pt, weight: "bold", font: "Fira Sans", fill: blue-zut)[ Przykład#if title != none [ — #title] ] #parbreak() #body #h(1fr) $blacksquare$ ] // ╔═══════════════════════════════════════════════════════╗ // ║ 3. GŁÓWNA FUNKCJA SZABLONU ║ // ╚═══════════════════════════════════════════════════════╝ /// Główna funkcja opakowująca dokument. /// /// Parametry: /// shorttitle – krótki tytuł pracy wyświetlany w nagłówku parzystych stron /// body – treść dokumentu #let zut-template( shorttitle: "", body, ) = { // ── 3.1 STRONA ────────────────────────────────────────── set page( paper: "a4", margin: ( top: 3.2cm, bottom: 3.5cm, inside: 3.5cm, // 2.5cm tekst + 1cm bindingoffset outside: 2.5cm, ), // ── Nagłówek ───────────────────────────────────────── // Strony nieparzyste (prawe): tytuł rozdziału + numer strony // Strony parzyste (lewe): numer strony + shorttitle // Strony otwierające rozdział: nagłówek ukryty (styl "plain") header: context { let pg = counter(page).get().first() let is-odd = calc.odd(pg) // Czy ta strona otwiera rozdział? (→ plain style: brak nagłówka) let chapter-locs = query(heading.where(level: 1)) let is-chapter-page = chapter-locs.any(h => counter(page).at(h.location()).first() == pg ) if not is-chapter-page { // Tytuł bieżącego rozdziału do nagłówka let prev = query(heading.where(level: 1).before(here())) let ch-label = if prev.len() > 0 { let h = prev.last() let num = counter(heading).at(h.location()) [#num.first().#h.body] } else { [] } set text(font: "Fira Sans", size: 10pt) if is-odd { // ── Nieparzysta (prawa) ────────────────────────── grid( columns: (1fr, auto), align: horizon, box( fill: blue-wi-20, width: 100%, inset: (x: 7pt, y: 4pt), )[#ch-label], box( fill: blue-zut, inset: (x: 7pt, y: 4pt), )[#text(fill: white, weight: "bold")[#pg]], ) } else { // ── Parzysta (lewa) ────────────────────────────── grid( columns: (auto, 1fr), align: horizon, box( fill: blue-zut, inset: (x: 7pt, y: 4pt), )[#text(fill: white, weight: "bold")[#pg]], box( fill: blue-wi-20, width: 100%, inset: (x: 7pt, y: 4pt), )[#shorttitle], ) } } }, // /header // ── Stopka ─────────────────────────────────────────── // Widoczna tylko na stronach otwierających rozdział (plain style). footer: context { let pg = counter(page).get().first() let chapter-locs = query(heading.where(level: 1)) let is-chapter-page = chapter-locs.any(h => counter(page).at(h.location()).first() == pg ) if is-chapter-page { set text(font: "Fira Sans", size: 10pt) align(right, box(fill: blue-zut, inset: (x: 7pt, y: 4pt))[ #text(fill: white, weight: "bold")[#pg] ] ) } }, numbering: "1", ) // /set page // ── 3.2 TEKST ─────────────────────────────────────────── set text(font: "Fira Sans", size: 12pt, lang: "pl") set par(justify: true, leading: 0.65em) // ── 3.3 LISTY ─────────────────────────────────────────── // \setlist{nolistsep} → spacing: 0.4em // \setlist[itemize]{label=--} set list(marker: [--], spacing: 0.4em, indent: 1em) set enum(spacing: 0.4em, indent: 1em) // ── 3.4 NAGŁÓWKI ──────────────────────────────────────── // Rozdział (\chapter) – level 1 // {\huge\sffamily\color{blueZUT}} + numer wysuniẹty o \hspace{-3ex} show heading.where(level: 1): it => { pagebreak(weak: true) v(1cm) context { set text(size: 24pt, weight: "bold", font: "Fira Sans", fill: blue-zut) if it.numbering != none { block(below: 0.6em)[ // Numer wysuniẹty w lewo (odpowiednik \hspace{-3ex}) #box(width: 0pt)[ #place(dx: -2em)[#counter(heading).display().] ] #h(1.2em) #it.body ] } else { block(below: 0.6em)[#it.body] } } } // Sekcja (\section) – level 2, wiszący numer w marginesie // \large\sffamily\bfseries + \llap{\color{blueZUT}{numer}\hspace{1em}} show heading.where(level: 2): it => { v(1.5em, weak: true) context { block(below: 0.5em, above: 0pt)[ #set text(size: 13pt, weight: "bold", font: "Fira Sans") #if it.numbering != none { // Numer wysuniẹty w lewo (llap) box(width: 0pt)[ #place(dx: -3em)[ #text(fill: blue-zut)[#counter(heading).display()] ] ] } #it.body ] } v(0.4em, weak: true) } // Podsekcja (\subsection) – level 3 show heading.where(level: 3): it => { v(1.2em, weak: true) context { block(below: 0.4em, above: 0pt)[ #set text(size: 12pt, weight: "bold", font: "Fira Sans") #if it.numbering != none { box(width: 0pt)[ #place(dx: -3em)[ #text(fill: blue-zut)[#counter(heading).display()] ] ] } #it.body ] } v(0.3em, weak: true) } // Podpodsekcja (\subsubsection) – level 4 show heading.where(level: 4): it => { v(1em, weak: true) context { block(below: 0.3em, above: 0pt)[ #set text(size: 11pt, weight: "bold", font: "Fira Sans") #if it.numbering != none { box(width: 0pt)[ #place(dx: -3em)[ #text(fill: blue-zut)[#counter(heading).display()] ] ] } #it.body ] } } // Paragraf (\paragraph) – level 5, inline show heading.where(level: 5): it => { v(0.8em, weak: true) text(size: 11pt, weight: "bold", font: "Fira Sans")[#it.body] v(0.15em, weak: true) } // ── 3.5 SPIS TREŚCI ───────────────────────────────────── // \titlecontents – numery, wcięcia, kolory, linie kropkowane set outline(indent: auto) show outline.entry: it => { if it.level == 1 { // Rozdział: +12pt przerwy, \large, blueZUT, pogrubiony v(12pt, weak: true) text(size: 11pt, weight: "bold", font: "Fira Sans", fill: blue-zut)[ #h(1.25cm) #it ] } else if it.level == 2 { // Sekcja: wcięcie 1.25cm, normalny v(3pt, weak: true) text(size: 10pt, font: "Fira Sans")[ #h(1.25cm) #it ] } else if it.level == 3 { // Podsekcja: wcięcie 2.5cm, small v(1pt, weak: true) text(size: 9pt, font: "Fira Sans")[ #h(2.5cm) #it ] } else { it } } // ── 3.6 BLOKI KODU ────────────────────────────────────── // Odpowiednik lstdefinestyle{mystyle}: // • małe litery, font monospace // • lewa kreska w kolorze blueWI // • wcięcia x: 5ex // • numery linii (Typst 0.12+: set raw(numbering: "1")) show raw.where(block: true): it => { block( width: 100%, fill: gray-zut.lighten(93%), stroke: (left: 2pt + blue-wi), inset: (x: 12pt, y: 9pt), above: 9pt, below: 9pt, radius: (right: 2pt), )[ #set text(size: 9.5pt, font: ("Fira Mono", "Courier New", "monospace")) #it ] } // Kod inline – dyskretne tło show raw.where(block: false): it => { box( fill: gray-zut.lighten(93%), inset: (x: 3pt, y: 1pt), radius: 2pt, )[ #set text(size: 10pt, font: ("Fira Mono", "Courier New", "monospace")) #it ] } // ── 3.7 PODPISY RYSUNKÓW I TABEL ──────────────────────── // \captionsetup[figure]{name={\small\sffamily\color{blueZUT} Rysunek}} // \captionsetup[table] {name={\small\sffamily\color{blueZUT} Tabela}} set figure(gap: 0.8em) show figure.caption: it => { set text(size: 9.5pt, font: "Fira Sans") let kind-label = if it.kind == image { [Rysunek] } else if it.kind == table { [Tabela] } else { [Algorytm] } [ #text(fill: blue-zut, weight: "bold")[ #kind-label #it.counter.display() ]#it.separator#it.body ] } // ── 3.8 TABELE ────────────────────────────────────────── // \usepackage{booktabs} – poziome linie tabel set table( stroke: none, inset: (x: 8pt, y: 5pt), ) // Linie nagłówka i dołu tabeli (booktabs-style) show table.cell.where(y: 0): set text(weight: "bold") show table: set block(above: 8pt, below: 8pt) // ── Treść dokumentu ───────────────────────────────────── body } // /zut-template