Skip to content

Commit

Permalink
Merge pull request #63 from ntjess/main
Browse files Browse the repository at this point in the history
Feature: Resizable text blocks
  • Loading branch information
andreasKroepelin authored Aug 21, 2023
2 parents 0b2a52c + 318413a commit 8484df0
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 8 deletions.
30 changes: 26 additions & 4 deletions examples/demo.typ
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
You can also see the slide number there.
]


#new-section-slide("Dynamic content")


Expand Down Expand Up @@ -306,18 +307,39 @@
explains how to do so.
]

#new-section-slide("Typst features")
#new-section-slide("Utilities")

#slide(title: "Use Typst!")[
Typst gives us so many cool things #footnote[For example footnotes!].
Use them!
#slide(title: [The `helpers` module])[
Polylux ships a `helpers` module with solutions for common tasks in slide
building.
]

#slide(title: [Fit to height])[
You can scale content such that it has a certain height using
`#fit-to-height(height, content)`:

#helpers.fit-to-height(2.5cm)[Height is `2.5cm`]
]

#slide(title: "Fill remaining space")[
This function also allows you to fill the remaining space by using fractions
as heights, i.e. `fit-to-height(1fr)[...]`:

#fit-to-height(1fr)[Wow!]
]

#slide(title: "Outline")[
Why not include an outline?
#polylux-outline(padding: 1em, enum-args: (tight: false))
]

#new-section-slide("Typst features")

#slide(title: "Use Typst!")[
Typst gives us so many cool things #footnote[For example footnotes!].
Use them!
]

#slide(title: "Bibliography")[
Let us cite something so we can have a bibliography: @A @B @C
#bibliography(title: none, "literature.bib")
Expand Down
102 changes: 101 additions & 1 deletion helpers.typ
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#import "logic.typ"

// SECTIONS

#let sections-state = state("polylux-sections", ())
#let register-section(name) = locate( loc => {
sections-state.update(sections => {
sections.push((body: name, loc: loc))
sections
})
})

#let current-section = locate( loc => {
let sections = sections-state.at(loc)
if sections.len() > 0 {
Expand All @@ -15,6 +18,7 @@
[]
}
})

#let polylux-outline(enum-args: (:), padding: 0pt) = locate( loc => {
let sections = sections-state.final(loc)
pad(padding, enum(
Expand All @@ -23,9 +27,105 @@
))
})


// PROGRESS

#let polylux-progress(ratio-to-content) = locate( loc => {
let ratio = logic.logical-slide.at(loc).first() / logic.logical-slide.final(loc).first()
ratio-to-content(ratio)
})

#let last-slide-number = locate(loc => logic.logical-slide.final(loc).first())
#let last-slide-number = locate(loc => logic.logical-slide.final(loc).first())


// HEIGHT FITTING

#let _size-to-pt(size, styles, container-dimension) = {
let to-convert = size
if type(size) == "ratio" {
to-convert = container-dimension * size
}
measure(v(to-convert), styles).height
}

#let _limit-content-width(width: none, body, container-size, styles) = {
let mutable-width = width
if width == none {
mutable-width = calc.min(container-size.width, measure(body, styles).width)
} else {
mutable-width = _size-to-pt(width, styles, container-size.width)
}
box(width: mutable-width, body)
}

#let fit-to-height(height, width: none, prescale-width: none, body) = {
// Place two labels with the requested vertical separation to be able to
// measure their vertical distance in pt.
// Using this approach instead of using `measure` allows us to accept fractions
// like `1fr` as well.
// The label must be attached to content, so we use a show rule that doesn't
// display anything as the anchor.
let before-label = label("polylux-fit-height-before")
let after-label = label("polylux-fit-height-after")
[
#show before-label: none
#show after-label: none
#v(1em)
hidden#before-label
#v(height)
hidden#after-label
]

locate(loc => {
let before = query(selector(before-label).before(loc), loc)
let before-pos = before.last().location().position()
let after = query(selector(after-label).before(loc), loc)
let after-pos = after.last().location().position()

let available-height = after-pos.y - before-pos.y

style(styles => {
layout(container-size => {
// Helper function to more easily grab absolute units
let get-pts(body, w-or-h) = {
let dim = if w-or-h == "w" {container-size.width} else {container-size.height}
_size-to-pt(body, styles, dim)
}

// Provide a sensible initial width, which will define initial scale parameters.
// Note this is different from the post-scale width, which is a limiting factor
// on the allowable scaling ratio
let boxed-content = _limit-content-width(
width: prescale-width, body, container-size, styles
)

// post-scaling width
let mutable-width = width
if width == none {
mutable-width = container-size.width
}
mutable-width = get-pts(mutable-width, "w")

let size = measure(boxed-content, styles)
let h-ratio = available-height / size.height
let w-ratio = mutable-width / size.width
let ratio = calc.min(h-ratio, w-ratio) * 100%

// If not boxed, the content can overflow to the next page even though it will fit.
// This is because scale doesn't update the layout information.
// Boxing in a container without clipping will inform typst that content
// will indeed fit in the remaining space
let new-width = size.width * ratio
place(
dy: -available-height,
box(
width: new-width,
height: available-height,
scale(x: ratio, y: ratio, origin: top + left, boxed-content)
)
)
})
})
})
}

1 change: 0 additions & 1 deletion logic.typ
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@
uncover((beginning: beginning), mode: mode, body)
}


#let polylux-slide(max-repetitions: 10, body) = {
locate( loc => {
if counter(page).at(loc).first() > 1 {
Expand Down
2 changes: 1 addition & 1 deletion polylux.typ
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
#import "logic.typ"
#import "logic.typ": polylux-slide, uncover, only, alternatives, one-by-one, line-by-line, pause, enable-handout-mode
#import "helpers.typ"
#import "helpers.typ": polylux-outline
#import "helpers.typ": polylux-outline, fit-to-height
4 changes: 3 additions & 1 deletion themes/clean.typ
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@
#let focus-slide(background: teal, foreground: white, body) = {
set page(fill: background, margin: 2em)
set text(fill: foreground, size: 1.5em)
logic.polylux-slide(align(horizon, body))
let content = { v(.1fr); body; v(.1fr) }
// logic.polylux-slide(align(horizon, body))
logic.polylux-slide(content)
}

#let new-section-slide(name) = {
Expand Down

0 comments on commit 8484df0

Please sign in to comment.