Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Ratio theme #160

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- [Metropolis](./themes/gallery/metropolis.md)
- [University](./themes/gallery/university.md)
- [Bipartite](./themes/gallery/bipartite.md)
- [Ratio](./themes/gallery/ratio.md)
- [Build your own](./themes/your-own.md)
- [Utilities](./utils/utils.md)
- [Side by side](./utils/side-by-side.md)
Expand Down
152 changes: 152 additions & 0 deletions book/src/themes/gallery/ratio.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Ratio theme

![ratio](ratio.png)

This theme is inspired by the Singapore beamer theme. It has a more modern look, but still features Singapore's navigation sections and sub-section circles.

Use it via

```typ
{{#include ../../IMPORT.typ}}
#import themes.ratio: *

#show: ratio-theme.with(
aspect-ratio: "16-9",
title: [Ratio theme],
abstract: [A theme about navigation and customization],
authors: (ratio-author("Theme Author", "Typst Community", "[email protected]"),),
version: "1.0.0",
date: datetime(year: 2024, month: 4, day: 4),
keywords: ("foo", "bar"),
options: (:),
)
```

By default it already generates a cover page and sets some document attributes based on your settings.
You can disable this with `cover: false`.

`ratio` uses polylux' section handling, the regular `#outline()` will not work
properly, use `#polylux-outline` instead.

## Options for initialization

The theme is highly customizable! If there's something you don't like or want to tweak, you probably can.

### The essentials

The essentials are separate keyword arguments to the `ratio-theme` call.

- `aspect-ratio`: The aspect ratio (16-9 by default).
- `cover`: Wether to include the cover page.
- `title`: Presentation title content
- `abstract`: An abstract or subtitle for your work. Set to `none` to disable.
- `authors`: An array of objects made with the custom `author(name:, affiliation:, email: )` method.
- `date`: A datetime object, defaults to today.
- `version`: A document version to display. Something like "Draft" or "1.0".
- `keywords`: Output document keywords to set.

### The `options` tweaks

The `options` keyword argument is special, it takes a dictionary with any of the following:

- `text`: Text style for the entire document.
- `register-headings`: Whether to register level 1 and 2 headings automatically as sections and subsections.
- `style-headings`: Enable/disable any styling applied to headings.
- `style-links`: Enable/disable any styling applied to links.
- `style-raw`: Enable/disable any styling applied to raw content.
- `hero`: What to show as the "hero" or background image on title slides. `auto` results in the theme's default background.
- `header`: What to display as the header ("navigation", "progress", content, or `none`).
- `footer`: What to display as the footer ("navigation", "progress", content, or `none`).
- `title-hero-color`: Tweak the background color for the coming title pages.
- `title-text`: Styling to apply to the entire title page's text.
- `title-heading-text`: Style of the title page's main title.
- `title-author-text`: Style of the title slide's author names.
- `title-affiliation-text`: Style of the title slide's affiliation entries.
- `title-abstract-text`: Style of the title slide's abstract.
- `title-version-text`: Style of the title slide's version text.
- `heading-texts`: The style to apply to heading text.
- Notice the `s`! It's an array of text styles for increasing heading depth!
- `heading-alignments`: The alignments to apply to headings.
- Notice the `s`! It's an array of alignments for increasing heading depth!
- `slide-box`: Arguments for the slide content's box container.
- `slide-grid`: Grid specification for the grid inside the box as arguments to `#grid()`.
- `slide-grid-cell`: Grid cell to use for main body content as arguments to `#grid.cell()`.
- `link-color`: The color to apply to the link anchor.
- `stroke-color`: The color to apply to strokes such as in tables.
- `fill-color`: The color to apply in fills such as in code blocks.
- `navigation-bar-color`: Navigation background color.
- `navigation-text`: Navigation bar text options for all text.
- `navigation-text-past`: Navigation bar text overrides for past sections.
- `navigation-text-current`: Navigation bar text overrides for the current section.
- `navigation-text-future`: Navigation bar text overrides for future sections.
- `navigation-shape-past`: Navigation bar shape for past subsections.
- `navigation-shape-current`: Navigation bar shape for current subsections.
- `navigation-shape-future`: Navigation bar shape for future subsections.
- `progress-bar-height`: Progress bar height.
- `progress-bar-color`: Progress bar background color.
- `progress-overlay-color`: Progress bar overlay color.
- `progress-text-color`: Progress bar text color.

## Slide functions

`ratio` provides the following custom slide functions:

- `title-slide(title, authors, abstract, date, version, keywords, foreground, background, register-section)` with all keyword arguments:
- `title`: Presentation title content. Defaults to `none`.
- `authors`: An array of objects made with the custom `author(name:, affiliation:, email: )` method. Defaults to `none`.
- `abstract`: An abstract or subtitle for your work. Defaults to `none`.
- `date`: A datetime object, defaults to `none`.
- `version`: A document version to display on the date line. Something like "Draft" or "1.0". Defaults to `none`.
- `keywords`: Keywords to display on the date line. Defaults to ().
- `foreground`: Content to include in front of the default text content.
- `background`: Content to include behind the default text content.
- `hero`: What to show as the "hero" or background image on title slides. `auto` results in the theme's default background.
- `slide(title, header, footer)[body]` with a title keyword argument and body positional.
- `title`: Section title will be added as a heading, too. Mostly for compatibility purposes with other themes.
- `header`: Header content override. Default is `auto` which draws the header according to the theme options. Set it to `none` to disable for this slide.
- `footer`: Footer content override. Default is `auto` which draws the footer according to the theme options. Set it to `none` to disable for this slide.
- `box`: Arguments to the slide's box. Set it to `auto` which draws from theme options, `none` to disable the use of a box or some other arguments to the `box()` function.
- `align`: Slide content alignment. Set it to `auto` to draw from theme options, `none` to disable further alignment.
- `body`: Your content such that you can type `#slide[my foo is my bar]`
- `centered-slide(header, footer)[body]` same as `slide` with all content `center + horizon`
- `bare-slide[body]`: For now just an alias of `polylux-slide`

See the [Customization](#customization) feature for ways to change these on the fly!

## Additional features

### Palette

Do you like theme colors? Ratio includes a default palette to pull from in the `ratio-palette` variable. That should make it easier to style things!

### Customization

Ratio's key feature is customization. It stores all it's options in a `ratio-options` state variable. You probably won't interact with that variable directly, but its defaults are included as the `ratio-defaults` variable for you to inspect!

```typ
// Careful, there are a lot of options!
#ratio-defaults
```

You can change the options in one of two ways:

```typ
// Register: replaces the option values given in this dictionary completely.
// For example, this disables the link styling with the little anchor:
#ratio-register((style-links: false))

// Update: recursively updates any dictionaries (i.e. for `text()` related items).
// For example, this only replaces the title text's fill and leaves other options intact.
#ratio-update((title-text: (fill: ratio-palette.danger)))
```

You can put these overrides halfway through your document to change things on the fly!

## Example code

The image at the top is created by the following code:

```typ
{{#include ../../IMPORT.typ}}
{{#include ratio.typ:3:}}
```
202 changes: 202 additions & 0 deletions book/src/themes/gallery/ratio.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
#import "../../../../polylux.typ": *

#import themes.ratio: *

#show: ratio-theme.with(
aspect-ratio: "16-9",
title: [Ratio theme],
abstract: [A theme about navigation and customization],
authors: (ratio-author("Theme Author", "Typst Community", "[email protected]"),),
version: "1.0.0",
date: datetime(year: 2024, month: 4, day: 4),
keywords: ("navigation", "customization"),
options: (:),
)

#centered-slide[
= Welcome!
]

#slide[
== Theme setup
The title page was the result of:

```typ
#import themes.ratio: *

#show: ratio-theme.with(
cover: true,
aspect-ratio: "16-9",
title: [Ratio theme],
abstract: [A theme about navigation and customization],
authors: (ratio-author("Theme Author", "Typst Community", "[email protected]"),),
version: "1.0.0",
date: datetime(year: 2024, month: 4, day: 4),
keywords: ("navigation", "customization"),
options: (:),
)
```

Which automatically generates a cover page if `cover` is set to `true`.
]

#slide[
= Navigation
Have you noticed the navigation bar at the top?

You can press the main section titles, or just one of the subsection dots.

Also, there's a progress bar at the bottom by default.

== Subsections become dots

The current section's dot is always "alight".

== So there's two dots for "Navigation"!

And they're both alight since we're on this page.

]

#slide[
The last subsection is still active because we haven't registered a new section
yet!
]

#slide[

#utils.register-section("Manual sections")
#utils.register-subsection("Manual subsection")

== Adding manual subsections

You can also manually register a new section using:

```typ
#utils.register-section("Manual sections")
#utils.register-subsection("Manual subsection")
```

Which is what we did at the start of this slide's code.

== Toggle headings registration
If you don't want headings to be registered by default, you can switch it
on/off:

```typ
#ratio-update((register-headings: false))
```
]

#slide[
= Customization

#set text(size: 15pt)
We all know that layouts work all of the time 99% of the time.

The `ratio-update` function updates option dictionaries *recursively* and thus
only updates what you specify.

The `ratio-register` function replaces values *completely*.

There's a handy `ratio-palette` variable with a pre-configured color palette,
but feel free to bring your own!

```typ
// Only update the heading color, not it's size:
#ratio-update((title-text: (fill: ratio-palette.warning))) // <- Notice the palette!
// Next title slide will feature a green background.
#ratio-register((title-hero-color: color.hsl(green)))

// Let's add some foreground and background content this time. We can place it anywhere!
#let fg = place(horizon + left, block(inset: 10%, width: 100%)[foreground.])
#let bg = place(
horizon + left,
block(inset: 30%, width: 100%)[#text(weight: "bold")[background.]],
)
#title-slide(title: "Green", register-section: true, foreground: fg, background: bg)

// This becomes...=>
```
]
#ratio-update((title-text: (fill: ratio-palette.warning)))
#ratio-register((title-hero-color: color.hsl(green)))
#let fg = place(horizon + left, block(inset: 10%, width: 100%)[foreground.])
#let bg = place(
horizon + left,
block(inset: 30%, width: 100%)[#text(weight: "bold")[background.]],
)
#title-slide(title: "Green", register-section: true, foreground: fg, background: bg)

#slide[
= Slide layout

== Alignment grid

By default Ratio uses a 7x7 `grid` wrapped in a content `box` that fills the
page's space \
between the header and footer. The grid has the following specifications:

```typ
#let slide-grid = (
rows: (auto, 1em, 3fr, auto, 5fr, 1em, auto),
columns: (auto, 2em, 1fr, auto, 1fr, 2.5em, auto),
gutter: 0pt,
)
```

Which achieves:
- edge content possible using placements in the first and last columns
- followed by padding around the main content
- content in the middle `(auto, auto)` cell
- "spring-loaded" positioning using the `fr` rows and columns
- The defaults roughly center the content on screen and push it slightly above the
horizon.
]

#slide(
grid-children: (grid.cell(x: 6, rowspan: 7, fill: red, align: horizon)[cell]),
)[
== Customizing the grid

The default slide function `#slide` allows for customization of this grid using
the `grid-args` and `grid-cell` keyword arguments per slide.

- `grid-args` fully customize the grid.
- `auto` means to use the grid settings from theme options.
- `none` means to disable the grid.
- anything else is treated as keyword arguments to `#grid`
- `grid-cell` the cell at which to put the body.
- `auto` means to put it at the cell as defined in theme options.
- `none` means to check if the body is an array:
- if it's an array, pass the array to `#grid` as the contents.
- if not, disable the grid functionality and use body as is.
- `grid-children` children to place on the grid. The bar on the right was achieved
with:\
`grid-children: (grid.cell(x: 6, rowspan: 7, fill: red),)`
]

#ratio-register((
slide-grid: (columns: (5em, auto, 10em), rows: (1em, auto, 2em)),
slide-grid-cell: (x: 1, y: 1),
))

#slide[
== Custom grid

If you're not satisfied with the default grid, you can tweak things in the init
function, too.

```typ
#show: ratio-theme.with(
//..,
options: (
slide-grid: (
columns: (5em, auto, 10em),
rows: (1em, auto, 2em),
),
slide-grid-cell: (x: 1, y: 1),
),
)
```
]
5 changes: 3 additions & 2 deletions scripts/generate-previews.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ function montage(imgs, annotation)
annotation
end


a = min(max(ceil(Int, sqrt(n)), 3), n)
b = ceil(Int, n / a)
b, a = minmax(a, b)
@assert a * b >= n
idcs = CartesianIndices((1:a, 1:b))
dims = size(first(imgs)) .* (b, a) .* .6 |> reverse

plt = plot(
size = dims,
background = :lightgray,
Expand Down Expand Up @@ -147,6 +147,7 @@ generate_previews([
typ2png(path = gallery, file = "metropolis"),
typ2png(path = gallery, file = "university"),
typ2png(path = gallery, file = "bipartite"),
typ2png(path = gallery, file = "ratio"),
typ2png(path = utils, file = "side-by-side"),
typ2png(path = utils, file = "side-by-side-kwargs"),
typ2png(path = utils, file = "fill-remaining"),
Expand Down
Loading