ft: add clean theme
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
**/*.pdf
|
||||
flake.lock
|
||||
51
README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Clean Polylux Template
|
||||
|
||||
This is a clean and dynamic presentation template for [Polylux](https://github.com/andreasKroepelin/polylux), a package for [Typst](https://typst.app/) to create nice looking presentations.
|
||||
|
||||
Initial work was already done, but I added lots of neat features, so now this template features:
|
||||
- An easy to use templating interface, which just requires some meta information
|
||||
- A footer with arbitrary text and a slide counter
|
||||
- A slide counter, that does not suck! (as it only counts real slides and shows a total amount)
|
||||
- Dynamic logos on the title slide
|
||||
- Dynamic coloring via variables
|
||||
- Automatic creation of a contents slide
|
||||
- Dynamic header on each slide showing the slide's name and current section
|
||||
- Focus slides
|
||||
|
||||
## Screenshots
|
||||
| Light Theme with Green Accent | Light Theme with Orange Accent | Dark Theme with Purple Accent |
|
||||
|:--:|:--:|:--:|
|
||||
||||
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## How to use
|
||||
See [presentation.typ](./presentation.typ) for a sample presentation.
|
||||
Make sure you have `typst` installed, otherwise you could use the provided Nix Flake with `nix develop .`
|
||||
|
||||
To just compile the presentation, run:
|
||||
```sh
|
||||
$ typst compile presentation.typ --open
|
||||
```
|
||||
|
||||
To have a live preview, run:
|
||||
```sh
|
||||
$ typst watch presentation.typ --open
|
||||
```
|
||||
|
||||
## Configure
|
||||
The entire templating part is done in [theme.typ](./theme.typ).
|
||||
Every major variable can be found towards the top of the file, marked with `CONFIG:` comments.
|
||||
Here you can configure the font and the color of the slides, the rest will be adjusted automatically.
|
||||
|
||||
|
||||
## Contribution
|
||||
Feel free to fork this repository and make adjustments as you wish, but I would appreciate a small notice somewhere.
|
||||
If you find visual bugs or have feature ideas, feel free to upstream them to this repository.
|
||||
|
||||
## Inspirations
|
||||
- [matze/mtheme](https://github.com/matze/mtheme)
|
||||
- [Enive](https://github.com/Enivex)
|
||||
- [hargoniX](https://github.com/hargoniX/)
|
||||
BIN
figures/ferris.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
figures/polylux.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
9
figures/typst.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg width="91" height="35" viewBox="0 0 91 35" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="logo">
|
||||
<path d="M7.88785 18.1481C7.88785 19.2805 8.05033 20.0404 8.3753 20.4278C8.70026 20.8152 9.29111 21.0089 10.1478 21.0089C11.0341 21.0089 12.1715 20.5619 13.56 19.6679L14.4463 21.143C11.8465 23.3184 9.70471 24.4061 8.02079 24.4061C6.33687 24.4061 5.00745 24.0038 4.03255 23.1992C3.05765 22.3648 2.5702 20.9046 2.5702 18.8186V7.10728H0.35451L0 5.45338L2.5702 4.64879V2.45849L7.88785 0V4.91699L13.1169 4.51469L12.6294 7.42018L7.88785 7.24138V18.1481Z" fill="currentColor"/>
|
||||
<path d="M17.5836 34.5977H16.8302C16.1212 33.3759 15.5747 31.6326 15.1906 29.3678L16.2098 28.742C17.0666 29.2784 17.8199 29.5466 18.4698 29.5466C19.8583 29.5466 20.9219 28.9059 21.6604 27.6245L23.1671 24.0932L16.3871 8.13538C16.0326 7.33078 15.7224 6.82418 15.4565 6.61558C15.1906 6.40698 14.6884 6.25798 13.9498 6.16858L13.6396 4.51469C16.003 4.75309 17.7017 4.87229 18.7357 4.87229C19.7697 4.87229 21.6161 4.75309 24.2749 4.51469L24.0977 6.07918C24.0386 6.10898 23.8761 6.15368 23.6102 6.21328C23.3739 6.27288 23.1671 6.33248 22.9898 6.39208C22.8421 6.42188 22.6649 6.46658 22.4581 6.52618C22.0445 6.70498 21.8377 6.92848 21.8377 7.19668C21.8377 7.40528 21.8968 7.71818 22.0149 8.13538L25.9145 18.1928L29.7255 7.95657C29.8141 7.68837 29.8585 7.43508 29.8585 7.19668C29.8585 6.66028 29.0756 6.30268 27.5098 6.12388L27.4212 4.55938C28.8688 4.76798 30.08 4.87229 31.0549 4.87229C32.0298 4.87229 33.6399 4.76798 35.8851 4.55938L35.5749 6.21328C34.8659 6.24308 34.3637 6.37718 34.0683 6.61558C33.8024 6.82418 33.5217 7.27118 33.2263 7.95657L23.9204 29.9042C22.591 33.0332 20.4787 34.5977 17.5836 34.5977Z" fill="currentColor"/>
|
||||
<path d="M49.1768 22.1264C50.329 22.1264 51.3039 21.4857 52.1015 20.2043C52.9287 18.8931 53.3423 16.9859 53.3423 14.4828C53.3423 9.83397 51.9981 7.50958 49.3098 7.50958C48.2167 7.50958 47.0202 8.12048 45.7204 9.34227V19.6232C46.0453 20.3384 46.5328 20.9344 47.1827 21.4112C47.8327 21.888 48.4974 22.1264 49.1768 22.1264ZM49.2655 35C46.518 34.7318 44.6568 34.5977 43.6819 34.5977C42.707 34.5977 40.7572 34.7318 37.8325 35L37.3894 33.3908C38.4529 33.1524 39.221 32.8842 39.6937 32.5862C40.1664 32.2882 40.4027 31.8263 40.4027 31.2005V8.89527C40.4027 7.88208 40.0187 7.37548 39.2506 7.37548L37.2121 7.64368L36.9906 5.94508C39.5312 4.81269 41.9389 4.14219 44.2137 3.93359L45.1443 4.96168C45.1443 5.61728 45.292 6.36228 45.5874 7.19668L47.5372 5.72158C48.8962 4.67859 50.1222 4.15709 51.2153 4.15709C53.9036 4.15709 55.883 4.97658 57.1533 6.61558C58.4236 8.25457 59.0588 10.6088 59.0588 13.6782C59.0588 16.7177 58.0987 19.2656 56.1784 21.3218C54.2581 23.378 51.7913 24.4061 48.778 24.4061C47.8031 24.4061 46.7839 24.0783 45.7204 23.4227V31.2899C45.7204 31.8561 45.9567 32.3031 46.4294 32.6309C47.1089 32.9289 47.9951 33.1673 49.0882 33.3461L49.5757 33.4355L49.2655 35Z" fill="currentColor"/>
|
||||
<path d="M67.3337 22.2605C68.0427 22.2605 68.6336 22.037 69.1063 21.59C69.5789 21.143 69.8153 20.5917 69.8153 19.9361C69.8153 19.2507 69.7267 18.7441 69.5494 18.4163C69.3722 18.0587 69.0767 17.7309 68.6631 17.4329C68.0723 16.9561 67.2303 16.4496 66.1373 15.9132C65.0737 15.3768 64.2318 14.9149 63.6114 14.5275C63.0205 14.1401 62.4297 13.5143 61.8388 12.6501C61.2775 11.7561 60.9969 10.728 60.9969 9.56577C60.9969 7.89698 61.6468 6.58578 62.9467 5.63218C64.2761 4.64879 65.9157 4.15709 67.8655 4.15709C69.8153 4.15709 72.031 4.49979 74.5126 5.18518C74.4239 7.12218 74.1728 8.76117 73.7592 10.1022L71.9867 10.5045C71.2777 7.64368 69.9335 6.21328 67.9541 6.21328C66.6247 6.21328 65.96 7.00298 65.96 8.58237C65.96 9.20817 66.2111 9.74457 66.7133 10.1916C67.2451 10.6386 68.0132 11.1154 69.0176 11.622C70.0221 12.0988 70.7459 12.4713 71.189 12.7395C71.6322 12.9779 72.223 13.3802 72.9616 13.9464C74.3205 15.0192 75 16.524 75 18.461C75 20.398 74.2614 21.8731 72.7843 22.8863C71.3072 23.8995 69.3574 24.4061 66.9349 24.4061C64.542 24.4061 62.4444 24.0038 60.6423 23.1992C60.5833 22.6926 60.5537 21.8135 60.5537 20.5619C60.5537 19.2805 60.5833 18.3865 60.6423 17.8799L62.8137 17.3883C63.0501 18.8484 63.5671 20.0255 64.3647 20.9195C65.1623 21.8135 66.152 22.2605 67.3337 22.2605Z" fill="currentColor"/>
|
||||
<path d="M84.4416 18.1481C84.4416 19.2805 84.604 20.0404 84.929 20.4278C85.254 20.8152 85.8448 21.0089 86.7016 21.0089C87.5878 21.0089 88.7252 20.5619 90.1137 19.6679L91 21.143C88.4003 23.3184 86.2584 24.4061 84.5745 24.4061C82.8906 24.4061 81.5612 24.0038 80.5863 23.1992C79.6114 22.3648 79.1239 20.9046 79.1239 18.8186V7.10728H76.9082L76.5537 5.45338L79.1239 4.64879V2.45849L84.4416 0V4.91699L89.6706 4.51469L89.1831 7.42018L84.4416 7.24138V18.1481Z" fill="currentColor"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.6 KiB |
35
flake.nix
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
description = "Nightly Typst with Typst LSP";
|
||||
|
||||
inputs.typst-lsp.url = "github:nvarner/typst-lsp";
|
||||
inputs.typst.url = "github:typst/typst";
|
||||
inputs.utils.url = "github:numtide/flake-utils";
|
||||
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
|
||||
outputs = {
|
||||
nixpkgs,
|
||||
utils,
|
||||
typst,
|
||||
typst-lsp,
|
||||
...
|
||||
}:
|
||||
utils.lib.eachDefaultSystem (system: let
|
||||
typst-overlay = _self: _super: {
|
||||
typst-lsp = typst-lsp.packages.${system}.default;
|
||||
typst = typst.packages.${system}.default.overrideAttrs (_old: {
|
||||
dontCheck = true;
|
||||
});
|
||||
};
|
||||
pkgs = nixpkgs.legacyPackages.${system}.appendOverlays [typst-overlay];
|
||||
typst-shell = pkgs.mkShell {
|
||||
nativeBuildInputs = [
|
||||
pkgs.typst-lsp
|
||||
pkgs.typst
|
||||
];
|
||||
};
|
||||
in {
|
||||
devShells.default = typst-shell;
|
||||
overlays.default = typst-overlay;
|
||||
legacyPackages = pkgs;
|
||||
});
|
||||
}
|
||||
41
presentation.typ
Normal file
@@ -0,0 +1,41 @@
|
||||
#import "theme.typ": *
|
||||
|
||||
#show: presentation.with(
|
||||
author: [Sample Author \<me\@example.org\>],
|
||||
title: [Sample Title],
|
||||
occasion: [Sample Occasion],
|
||||
date: [01.01.1970],
|
||||
logos: ("figures/typst.svg", "figures/polylux.png", "figures/ferris.png"),
|
||||
logo_height: 40%,
|
||||
footer: [This is a really cool footer],
|
||||
)
|
||||
|
||||
#section("My Section")
|
||||
#slide(title: "My Title")[
|
||||
#grid(
|
||||
columns: (50%, 50%),
|
||||
[
|
||||
- #lorem(10)
|
||||
- #lorem(10)
|
||||
- #lorem(10)
|
||||
- #lorem(10)
|
||||
],
|
||||
image("figures/ferris.png")
|
||||
)
|
||||
]
|
||||
|
||||
#focus-slide()[
|
||||
We need to focus now...
|
||||
]
|
||||
|
||||
#slide(title: "Some code!")[
|
||||
#figure(
|
||||
sourcecode(```rust
|
||||
enum Foo {
|
||||
Bar1(Box<Foo>),
|
||||
Bar2(String),
|
||||
}
|
||||
```),
|
||||
caption: [Some awesome Rust!]
|
||||
)
|
||||
]
|
||||
BIN
screenshots/contents.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
screenshots/dark1.png
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
screenshots/light1.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
screenshots/light2.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
screenshots/titlepage.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
191
theme.typ
Normal file
@@ -0,0 +1,191 @@
|
||||
#import "@preview/polylux:0.3.1": *
|
||||
#import "@preview/codelst:1.0.0": sourcecode
|
||||
|
||||
// CONFIG: Font
|
||||
#let font = "Roboto"
|
||||
#let weight = "light"
|
||||
#let size = 20pt
|
||||
|
||||
// CONFIG: Color
|
||||
#let color-primary = rgb("#66A182")
|
||||
#let color-foreground = rgb("#5c6a72")
|
||||
#let color-background = rgb("#ffffff")
|
||||
|
||||
#let footer-lighten-value = 50% // how much lighter the color of the footer is
|
||||
#let section-foreground = color-background // color of text on section slide and headers
|
||||
#let focus-background = color-foreground // background of the focus slide
|
||||
#let focus-foreground = color-background // foreground of focus slide
|
||||
|
||||
// Footer in the bottom left
|
||||
#let custom-footer = state("custom-footer", none)
|
||||
|
||||
// Last section in the top left
|
||||
#let last-section = state("last-section", none)
|
||||
|
||||
// A normal slide
|
||||
#let slide(title: none, is_toc: false, body) = {
|
||||
let header-cell = block.with(
|
||||
width: 100%,
|
||||
height: 100%,
|
||||
above: 0pt,
|
||||
below: 0pt,
|
||||
breakable: false
|
||||
)
|
||||
|
||||
// Bar in the top
|
||||
let header = {
|
||||
set align(top)
|
||||
if title != none {
|
||||
show: header-cell.with(fill: color-primary, inset: 1.2em)
|
||||
set align(horizon)
|
||||
|
||||
if not is_toc {
|
||||
text(fill: section-foreground, size: 0.6em, last-section.display())
|
||||
text([\ ])
|
||||
}
|
||||
text(fill: section-foreground, size: 1.2em, strong(title))
|
||||
|
||||
} else { [] }
|
||||
}
|
||||
|
||||
// Footer with text on the left and slide count on the right
|
||||
let footer = {
|
||||
set text(size: 0.6em)
|
||||
show: pad.with(1em)
|
||||
set align(bottom)
|
||||
let footer-color = color-foreground.lighten(footer-lighten-value)
|
||||
text(fill: footer-color, custom-footer.display())
|
||||
h(1fr)
|
||||
text(fill: footer-color, [#logic.logical-slide.display()/#utils.last-slide-number])
|
||||
}
|
||||
|
||||
set page(
|
||||
header: header,
|
||||
footer: if not is_toc { footer } else [],
|
||||
margin: (top: 5em),
|
||||
fill: color-background,
|
||||
)
|
||||
|
||||
let content = {
|
||||
show: align.with(horizon)
|
||||
show: pad.with(left: 2em, right: 2em, top: -1.5em)
|
||||
set text(fill: color-foreground)
|
||||
body
|
||||
}
|
||||
|
||||
logic.polylux-slide(content)
|
||||
|
||||
if is_toc {
|
||||
// Don't count TOC slide towards slide count
|
||||
logic.logical-slide.update(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The actual presentation main
|
||||
#let presentation(
|
||||
aspect-ratio: "16-9",
|
||||
title: [Sample title],
|
||||
occasion: [Sample occasion],
|
||||
author: [Sample Author],
|
||||
date: [01.01.1970],
|
||||
logos: (),
|
||||
logo_height: 50%,
|
||||
footer: [],
|
||||
body
|
||||
) = {
|
||||
set text(font: font, weight: weight, size: size)
|
||||
set strong(delta: 100)
|
||||
set par(justify: true)
|
||||
|
||||
set page(
|
||||
paper: "presentation-" + aspect-ratio,
|
||||
fill: color-background,
|
||||
margin: 0em,
|
||||
header: none,
|
||||
footer: none,
|
||||
)
|
||||
|
||||
// save foother to global state
|
||||
custom-footer.update(footer)
|
||||
|
||||
let title-slide = {
|
||||
set text(fill: color-foreground, size)
|
||||
set align(center + horizon)
|
||||
|
||||
block(width: 100%, inset: 2em, {
|
||||
// Logo
|
||||
if type(logos) == type("string") { // fix buggy behavior, with a single entry
|
||||
align(center+horizon, image(logos, height: logo_height))
|
||||
} else if logos.len() == 0 {
|
||||
// Do not show any logos
|
||||
} else {
|
||||
grid(
|
||||
columns: logos.len(),
|
||||
..logos.map((logo) => (align(center+horizon, image(logo, width: logo_height))))
|
||||
)
|
||||
}
|
||||
|
||||
text(size: 1.3em, strong(title))
|
||||
|
||||
line(length: 100%, stroke: .05em + color-primary)
|
||||
|
||||
set text(size: .8em)
|
||||
h(1fr)
|
||||
if author != none {
|
||||
block(spacing: 1em, author)
|
||||
}
|
||||
if date != none {
|
||||
block(spacing: 1em, date)
|
||||
}
|
||||
set text(size: .8em)
|
||||
|
||||
h(1fr)
|
||||
if occasion != none {
|
||||
set text(weight: "regular")
|
||||
block(spacing: 1em, occasion)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
logic.polylux-slide(title-slide)
|
||||
|
||||
// Show TOC
|
||||
slide(title: "Contents", is_toc: true)[
|
||||
#utils.polylux-outline(enum-args: (tight: false,))
|
||||
]
|
||||
|
||||
body
|
||||
}
|
||||
|
||||
|
||||
// Section brake slides with big title printed
|
||||
#let section(name) = {
|
||||
set page(fill: color-primary)
|
||||
let content = {
|
||||
utils.register-section(name)
|
||||
set align(horizon + center)
|
||||
show: pad.with(20%)
|
||||
set text(size: 2em, weight: "bold", fill: section-foreground)
|
||||
name
|
||||
}
|
||||
|
||||
logic.polylux-slide(content)
|
||||
|
||||
// Do not count section slides towards total slide count
|
||||
logic.logical-slide.update(i => i - 1)
|
||||
|
||||
// Update last section name to display it in the following slides
|
||||
last-section.update(name)
|
||||
}
|
||||
|
||||
// Only show the text centered and big (good for a final slide)
|
||||
#let focus-slide(body) = {
|
||||
set page(fill: focus-background, margin: 2em)
|
||||
set text(fill: focus-foreground, size: 1.5em)
|
||||
logic.polylux-slide(align(horizon + center, body))
|
||||
|
||||
// Do not count focus slides towards total slide count
|
||||
logic.logical-slide.update(i => i - 1)
|
||||
}
|
||||