How to derive specialised slides from a general slide function in touying?

Hello there,

I am currently writing my own presentation theme using the touying package.

I stumbled over an issue with having similar slides, in different functions. My goal is, to have a general color-slide() function, which will be called by wrapper functions. These functions shall then set an option in color-slide() to adjust the color of the header.

This is an (not compiling) example of how I’d approach this:

#import "@preview/touying:0.6.1": *
#import "@preview/showybox:2.0.4": *
#import "@preview/unify:0.7.1": *

#let dk0tu-blue = rgb("#003153")  // Berliner Blau,
#let dk0tu-green = rgb("#007b69")  // TUB GrΓΌn, AFuTUB-Kurs, Klasse E
#let dk0tu-orange = rgb("#f7941d")  // TUB Orange, AFuTUB-Kurs Klasse A
#let dk0tu-lightblue = rgb("#0b7a9b")  // TUB Blau, Community
#let dk0tu-red = rgb("#c9252c")  // TUB Rot, Kurs Ops


#let colored_slide(title: auto, header-color, ..args) = touying-slide-wrapper(self => {
  if title != auto {
    self.store.title = title
  }
  // set page
  let header_container(self) = {
    let parent = self

    // Header-line with chapter title
    block(
      width: 50%,
      height: 1em,
      fill: header-color,
      inset: .5em,
      [
        #set align(horizon + right)
        #set text(fill: parent.colors.neutral-lightest, size: .6em)
        #utils.display-current-heading(level:1)
      ]
    )

    // Slide Heading
    block(
      inset: 2%,
      outset: 2%,
      [
        #set text(size: 1.3em)
        #set align(bottom)
        #h(.5em)
        #if title != auto {
          text(self.store.title, size: 24pt)
        } else {
          utils.display-current-heading(level:2)
        }
      ]
    )
  }

  //let body_title(self) = {
  //  text(self.store.title, size: 24pt)
  //}

  let footer(self) = {
    set align(bottom)
    show: pad.with(.4em)
    set text(fill: self.colors.neutral-darkest, size: .6em)
    utils.call-or-display(self, self.store.footer)
    h(1fr)
    context utils.slide-counter.display() + " / " + utils.last-slide-number
  }
  self = utils.merge-dicts(
    self,
    config-page(
      header: header_container,
      footer: footer,
      background: image("./misc/dk0tu_rooftop_background.svg",width: 125%,),
    ),
  )

  touying-slide(self: self, ..args)
})


// Startup and summary slides (orange)
#let slide(title: auto, ..args) = colored_slide(title, dk0tu-blue, ..args)
#let summary-slide(title: auto, ..args) = colored_slide(title, dk0tu-red, ..args)
#let a-slide(title: auto, ..args) = colored_slide(title, dk0tu-orange, ..args)
#let e-slide(title: auto, ..args) = colored_slide(title, dk0tu-green, ..args)


//
// General theme definition
//
#let dk0tu-theme(
  aspect-ratio: "16-9",
  footer: none,
  ..args,
  body,
) = {
  // Global scoped configurations
  set text(
    // font: "Libertinus Sans",
    font: "New Computer Modern Sans",
    size: 20pt
    )

  // set url-link stile to Monospace
  show link: set text(
    font: "New Computer Modern Mono",
  )

  set align(horizon)

  show: touying-slides.with(
    config-page(
      paper: "presentation-" + aspect-ratio,
      margin: (top: 4em, bottom: 1.5em, x: 2em),
    ),
    config-common(
      slide-fn: slide,
      // No slides on new sections
      // new-section-slide-fn: new-section-slide,
    ),
    config-methods(
      alert: utils.alert-with-primary-color,
    ),
    // AFuTUB Style colors from https://git.dk0tu.de/afutub/styles
    config-colors(
      primary: rgb("#003153"),  // Berliner Blau,
      secondary: rgb("#007b69"),  // TUB GrΓΌn, AFuTUB-Kurs, Klasse E
      tertiary: rgb("#f7941d"),  // TUB Orange, AFuTUB-Kurs Klasse A
      //neutral-default: rgb("#0b7a9b"),  // TUB Blau, Community
      //neutral-default: rgb("#0b7a9b"),  // TUB Rot, Kurs Ops
      neutral-lightest: rgb("#ffffff"),
      neutral-darkest: rgb("#000000"),
    ),
    config-store(
      title: none,
      footer: footer,
    ),
    ..args,
  )

  body
}

#let dk0tu-box(..body) = showybox(
    shadow: (
      color: black.lighten(55%),
      offset: 3pt,
      sep-thickness: 0pt,
    ),
    frame: (
      title-color: rgb("#ddeef8"),
      body-color: rgb("#f4f9fd"),
      thickness: (left: 0pt,),
      border-color: rgb("#f4f9fd"),
    ),
    title-style: (
      color: black,
    ),
    ..body
  )

This is a presentation, that I would expect to work, but unfortunately triggers a compilation error:

#import "@preview/touying:0.6.1": *
#import "dk0tu_test.typ": *
#import "@preview/showybox:2.0.4": *
#import "@preview/unify:0.7.1": unit


#show: dk0tu-theme.with(aspect-ratio: "16-9",
  footer: self => self.info.institution,
  config-info(
    title: [Technik Klasse E 01:],
    subtitle: [Mathematische Grundkenntnisse und Einheiten],
    // author: ["DK0TU", Amateurfunkgruppe der TU Berlin],
    //date: datetime.today(),
    //institution: [Institution],
  ),
)

= Einleitung

== Zusammenfassung
#summary-slide()[
  Letzte Woche:

  - Ein Thema
  - Zweites Thema
  - Abschluss

  Heute: Neues Thema
]

#slide(title: "Einleitung")[
  Zu Beginn eine kurze Wiederholung der benΓΆtigten mathematischen Grundlagen, um das Schulwissen kurz aufzufrischen.
]

= Grâßen und Einheiten

== SI-Basissystem

SI#footnote[SystΓ¨me international d’unitΓ©s, ab 1790 von franz. Akademie der
Wissenschaften entwickelt, immer wieder erweitert]-Einheiten: Weitest
verbreitetes System seit *Meterkonvention* 1875 durch 17~Staaten.

#v(1em)

Eigenschaften:

- basiert auf metrischen Grâßen
- dezimal (Basis 10)
- kohΓ€rentes Einheitensystem#footnote[alles aus Basiseinheiten ableitbar ohne zusΓ€tzliche Faktoren]
- sieben Basiseinheiten

#v(1em)
#pause
Welche Einheiten gibt es und welche Grâßen beschreiben sie?


== SI-Basissystem

#e-slide[
  #dk0tu-box()[
    #table(
      columns: (auto, auto),
      inset: 10pt,
      align: horizon,
      stroke: none,
      //table.header(
      //  [], [*Volume*], [*Parameters*],
      //),
      [#unit("meter") / Meter], [LΓ€nge],
      [#unit("A") / Ampere], [StromstΓ€rke],
      [#unit("mol") / Mol], [Stoffmenge/Substanzmenge],
      [#unit("kg") / Kilogramm], [Masse],
      [#unit("K") / Kelvin], [Temperatur],
      [#unit("cd") / Candela], [LichtstΓ€rke],
      [#unit("second") / Sekunde], [Zeit],
    )
  ]

  #pause
  Kleiner Ausflug: SI vs. Imperial System...
]

#a-slide()[
  #figure(
    image("../Ressourcen/Abbildungen/afutub-us_vs_the_world_units.svg",
      height: 90%
    )
  )
]

Compiling these, results in this error:

error: expected color, gradient, tiling, or none, found auto
   β”Œβ”€ dk0tu_test.typ:25:12
   β”‚
25 β”‚       fill: header-color,
   β”‚             ^^^^^^^^^^^^

help: error occurred in this call of function `header_container`
    β”Œβ”€ @preview/touying:0.6.1/src/utils.typ:224:9
    β”‚
224 β”‚     it = it(self)
    β”‚          ^^^^^^^^

help: error occurred in this call of function `call-or-display`
     β”Œβ”€ @preview/touying:0.6.1/src/core.typ:1568:15
     β”‚
1568 β”‚   let header = utils.call-or-display(self, self.page.at("header", default: none))
     β”‚                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

help: error occurred in this call of function `_get-header-footer`
     β”Œβ”€ @preview/touying:0.6.1/src/core.typ:1807:25
     β”‚
1807 β”‚   let (header, footer) = _get-header-footer(self)
     β”‚                          ^^^^^^^^^^^^^^^^^^^^^^^^

help: error occurred in this call of function `touying-slide`
   β”Œβ”€ dk0tu_test.typ:73:2
   β”‚
73 β”‚   touying-slide(self: self, ..args)
   β”‚   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

help: error occurred in this function call
    β”Œβ”€ @preview/touying:0.6.1/src/core.typ:167:6
    β”‚
167 β”‚       slide-fn(self)
    β”‚       ^^^^^^^^^^^^^^

help: error occurred in this call of function `call-slide-fn-and-reset`
    β”Œβ”€ @preview/touying:0.6.1/src/core.typ:223:89
    β”‚  
223 β”‚         (cont, recaller-map, current-headings, current-slide, new-start, is-first-slide) = call-slide-fn-and-reset(
    β”‚ ╭──────────────────────────────────────────────────────────────────────────────────────────^
224 β”‚ β”‚         self + (headings: current-headings, is-first-slide: is-first-slide),
225 β”‚ β”‚         already-slide-wrapper: true,
226 β”‚ β”‚         child.value.fn,
227 β”‚ β”‚         none,
228 β”‚ β”‚         recaller-map,
229 β”‚ β”‚       )
    β”‚ ╰───────^

At the moment I duplicate the code of the colored-slide function for each of the functions. This works, but it produces a lot of code.

Do you have an idea, how to solve this? Thank you very much in advance!

i’m not sure what your specific issue is because your code isn’t complete, but generally you can β€œpick” keys out of dicts like this:

let (non-arg-1, non-arg-2, ..touying-args) = args.named()

now, touying-args contains all of args.named() except for non-arg-1 and non-arg-2

1 Like

Hi @mhuebner, could you maybe try to revise your post’s title to be a complete question as per the question guidelines:

Good titles are questions you would ask your friend about Typst.

A good title makes the topic easier to grasp, increasing your chances of getting a good answer quickly. We also hope by adhering to this, we make the information in this forum easy to find in the future. Thanks!

Thank you for the hint. I revised the title and first post. Hopefully it fits better now. :)

1 Like

Thank you for that approach. I did revise the first posting, as suggested by @SillyFreak. Do you think that should still apply? As far as I thought about it, the header-color option should be a named argument, right?