#import "@preview/touying:0.6.1": * #let _tblock(self: none, title: none, it) = { grid(columns: 1, row-gutter: 0pt, block( fill: self.colors.primary-dark, width: 100%, radius: (top: 6pt), inset: (top: 0.4em, bottom: 0.3em, left: 0.5em, right: 0.5em), text(fill: self.colors.neutral-lightest, weight: "bold", title), ), rect( fill: gradient.linear(self.colors.primary-dark, self.colors.primary.lighten(90%), angle: 90deg), width: 100%, height: 4pt, ), block( fill: self.colors.primary.lighten(90%), width: 100%, radius: (bottom: 6pt), inset: (top: 0.4em, bottom: 0.5em, left: 0.5em, right: 0.5em), it, )) } #let tblock(title: none, it) = touying-fn-wrapper(_tblock.with(title: title, it)) #let slide( title: auto, header: auto, footer: auto, align: auto, config: (:), repeat: auto, setting: body => body, composer: auto, ..bodies, ) = touying-slide-wrapper(self => { if align != auto { self.store.align = align } if title != auto { self.store.title = title } if header != auto { self.store.header = header } if footer != auto { self.store.footer = footer } let new-setting = body => { show: std.align.with(self.store.align) show: setting body } touying-slide(self: self, config: config, repeat: repeat, setting: new-setting, composer: composer, ..bodies) }) #let title-slide(config: (:), ..args) = touying-slide-wrapper(self => { self = utils.merge-dicts(self, config) self.store.title = none let info = self.info + args.named() info.authors = { let authors = if "authors" in info { info.authors } else { info.author } if type(authors) == array { authors } else { (authors,) } } let body = { show: std.align.with(center + horizon) block(fill: self.colors.primary, inset: 1.5em, radius: 0.5em, breakable: false, { text(size: 1.2em, fill: self.colors.neutral-lightest, weight: "bold", info.title) if info.subtitle != none { parbreak() text(size: 1.0em, fill: self.colors.neutral-lightest, weight: "bold", info.subtitle) } }) // authors grid( columns: (1fr,) * calc.min(info.authors.len(), 3), column-gutter: 1em, row-gutter: 1em, ..info.authors.map(author => text(fill: black, author)), ) v(0.5em) // institution if info.institution != none { parbreak() text(size: 0.7em, info.institution) } // date if info.date != none { parbreak() text(size: 1.0em, utils.display-info-date(self)) } } touying-slide(self: self, body) }) #let outline-slide(config: (:), title: utils.i18n-outline-title, numbered: true, level: none, ..args) = touying-slide-wrapper( self => { self.store.title = title touying-slide( self: self, config: config, std.align( self.store.align, components.adaptive-columns(text(fill: self.colors.primary, weight: "bold", components.custom-progressive-outline( level: level, alpha: self.store.alpha, indent: (0em, 1em), vspace: (.4em,), numbered: (numbered,), depth: 1, ..args.named(), ))) + args.pos().sum(default: none), ), ) }, ) #let new-section-slide(config: (:), title: utils.i18n-outline-title, level: 1, numbered: true, ..args, body) = outline-slide(config: config, title: title, level: level, numbered: numbered, ..args, body) #let focus-slide(config: (:), align: horizon + center, body) = touying-slide-wrapper(self => { self = utils.merge-dicts( self, config-common(freeze-slide-counter: true), config-page(fill: self.colors.primary, margin: 2em, header: none, footer: none), ) set text(fill: self.colors.neutral-lightest, weight: "bold", size: 1.5em) touying-slide(self: self, config: config, std.align(align, body)) }) #let ending-slide(config: (:), title: none, body) = touying-slide-wrapper(self => { let content = { set std.align(center + horizon) if title != none { block( fill: self.colors.tertiary, inset: (top: 0.7em, bottom: 0.7em, left: 3em, right: 3em), radius: 0.5em, text(size: 1.5em, fill: self.colors.neutral-lightest, title), ) } body } touying-slide(self: self, config: config, content) }) #let dm-unipi-theme( aspect-ratio: "16-9", align: horizon, alpha: 20%, title: self => utils.display-current-heading(depth: self.slide-level), header-right: self => self.info.logo, progress-bar: true, footer-columns: (25%, 1fr, 5em), footer-a: self => self.info.author, footer-c: self => if self.info.short-title == auto { self.info.title } else { self.info.short-title }, footer-d: context utils.slide-counter.display() + " / " + utils.last-slide-number, ..args, body, ) = { let header(self) = { set std.align(top) grid( rows: (auto, auto), utils.call-or-display(self, self.store.navigation), utils.call-or-display(self, self.store.header), ) } let footer(self) = { set text(size: .5em) set std.align(center + bottom) grid( rows: (auto, auto), utils.call-or-display(self, self.store.footer), if self.store.progress-bar { utils.call-or-display(self, components.progress-bar(height: 2pt, self.colors.primary, self.colors.neutral-lightest)) }, ) } show: touying-slides.with( config-page( paper: "presentation-" + aspect-ratio, header: header, footer: footer, header-ascent: 0em, footer-descent: 0em, margin: (top: 3.5em, bottom: 2.5em, x: 2.5em), ), config-common(slide-fn: slide, new-section-slide-fn: new-section-slide), config-methods(init: (self: none, body) => { set text(size: 18pt, font: "Open Sans") set par(leading: 0.75em) set list(marker: { place(top + left, dy: 0.2em, circle(fill: self.colors.primary, radius: 3pt)) h(0.25em) }) show figure.caption: set text(size: 0.6em) show footnote.entry: set text(size: 0.6em) show heading: set text(fill: self.colors.primary) show link: it => if type(it.dest) == str { set text(fill: self.colors.primary) it } else { it } show figure.where(kind: table): set figure.caption(position: top) body }, alert: utils.alert-with-primary-color, tblock: _tblock), config-colors( primary: rgb("#003c71"), primary-dark: rgb("#005baa"), secondary: rgb("#ffffff"), neutral-lightest: rgb("#ffffff"), neutral-darkest: rgb("#001c35"), ), config-store( align: align, alpha: alpha, title: title, header-right: header-right, progress-bar: progress-bar, footer-columns: footer-columns, footer-a: footer-a, footer-c: footer-c, footer-d: footer-d, navigation: self => components.simple-navigation( self: self, primary: white, secondary: gray, background: self.colors.neutral-darkest, logo: utils.call-or-display(self, self.store.header-right), ), header: self => if self.store.title != none { block( width: 100%, height: 2em, fill: self.colors.primary, place( left + horizon, text(fill: self.colors.neutral-lightest, weight: 600, size: 1.2em, utils.call-or-display(self, self.store.title)), dx: 1.5em, ), ) }, footer: self => { let cell(fill: none, it) = rect( width: 100%, height: 100%, inset: 1mm, outset: 0mm, fill: fill, stroke: none, std.align(horizon, text(fill: self.colors.neutral-lightest, it)), ) grid( columns: self.store.footer-columns, rows: (1.5em, auto), cell(fill: self.colors.neutral-darkest, utils.call-or-display(self, self.store.footer-a)), cell(fill: self.colors.primary, utils.call-or-display(self, self.store.footer-c)), cell(fill: self.colors.primary, utils.call-or-display(self, self.store.footer-d)), ) }, ), ..args, ) body }