diff --git a/logic.typ b/logic.typ index 1d2b86f..3767903 100644 --- a/logic.typ +++ b/logic.typ @@ -1,3 +1,5 @@ +#import "utils/pdfpc.typ": register_page; + #let subslide = counter("subslide") #let pause-counter = counter("pause-counter") #let logical-slide = counter("logical-slide") @@ -294,14 +296,7 @@ if curr-subslide <= repetitions.at(loc).first() { if curr-subslide > 1 { pagebreak(weak: true) } set heading(outlined: false) if curr-subslide > 1 - - [ - #metadata((t: "NewSlide")) - #metadata((t: "Idx", v: counter(page).at(loc).first() - 1)) - #metadata((t: "Overlay", v: curr-subslide - 1)) - #metadata((t: "LogicalSlide", v: logical-slide.at(loc).first())) - ] - + register_page(counter(page).at(loc).first() - 1, logical-slide.at(loc).first(), curr-subslide - 1); body } }) diff --git a/themes/bipartite.typ b/themes/bipartite.typ index dc3bcbe..cd2be96 100644 --- a/themes/bipartite.typ +++ b/themes/bipartite.typ @@ -1,6 +1,7 @@ // This theme is inspired by https://slidesgo.com/theme/modern-annual-report #import "../logic.typ" +#import "../utils/pdfpc.typ": meta_out; #let bipartite-dark = rgb("#192e41") @@ -17,6 +18,7 @@ ) body + meta_out(); } #let title-slide(title: [], subtitle: none, author: [], date: none) = { diff --git a/themes/clean.typ b/themes/clean.typ index a37905c..d31c8ea 100644 --- a/themes/clean.typ +++ b/themes/clean.typ @@ -3,6 +3,7 @@ #import "../logic.typ" #import "../utils/utils.typ" +#import "../utils/pdfpc.typ": meta_out; #let clean-footer = state("clean-footer", []) #let clean-short-title = state("clean-short-title", none) @@ -33,6 +34,7 @@ clean-logo.update(logo) body + meta_out(); } diff --git a/themes/metropolis.typ b/themes/metropolis.typ index cb1a7f2..5b7caa1 100644 --- a/themes/metropolis.typ +++ b/themes/metropolis.typ @@ -9,6 +9,7 @@ #import "../logic.typ" #import "../utils/utils.typ" +#import "../utils/pdfpc.typ": meta_out; #let m-dark-teal = rgb("#23373b") #let m-light-brown = rgb("#eb811b") @@ -48,6 +49,7 @@ m-footer.update(footer) body + meta_out(); } #let title-slide( diff --git a/themes/simple.typ b/themes/simple.typ index 89b0a99..c1932a1 100644 --- a/themes/simple.typ +++ b/themes/simple.typ @@ -1,4 +1,5 @@ #import "../logic.typ" +#import "../utils/pdfpc.typ": meta_out; #let simple-footer = state("simple-footer", []) @@ -26,6 +27,7 @@ simple-footer.update(footer) body + meta_out(); } #let centered-slide(body) = { diff --git a/themes/university.typ b/themes/university.typ index f78b2fe..47ab7da 100644 --- a/themes/university.typ +++ b/themes/university.typ @@ -1,5 +1,6 @@ #import "../logic.typ" #import "../utils/utils.typ" +#import "../utils/pdfpc.typ": meta_out; // University theme // @@ -41,6 +42,7 @@ uni-short-date.update(short-date) body + meta_out(); } #let title-slide( diff --git a/utils/pdfpc.typ b/utils/pdfpc.typ index 27d9e6c..3968680 100644 --- a/utils/pdfpc.typ +++ b/utils/pdfpc.typ @@ -1,3 +1,37 @@ +#let pdfpc_metadata = state("polylux_pdfpc_metadata", ( + pdfpcFormat: 2, + pages: () +)); + +#let set_or_fail(key, value) = { + pdfpc_metadata.update(m=>{ + assert(key not in m.keys(), message: "The key "+key+" can only be set once."); + m.insert(key, value); + m + }) +} + +#let register_page(idx, logicalSlide, overlay) = { + pdfpc_metadata.update(m=>{ + let entry = ( + idx: idx, + label: str(logicalSlide), + overlay: overlay + ); + + if(overlay>0) { + entry.forcedOverlay = true; + } + + m.pages.push(entry); + m + }) +} + +#let meta_out() = { + pdfpc_metadata.display(m=>[#metadata(m)]); +} + #let speaker-note(text) = { let text = if type(text) == "string" { text @@ -6,20 +40,27 @@ } else { panic("A note must either be a string or a raw block") } - [ #metadata((t: "Note", v: text)) ] + pdfpc_metadata.update(m=>{ + m.pages.last().insert("note", m.pages.last().at("note", default: "")+text); + m + }) } -#let end-slide = [ - #metadata((t: "EndSlide")) -] +#let end-slide = { + pdfpc_metadata.display(m=>set_or_fail("endSlide", int(m.pages.last().label)-1)) + +} -#let save-slide = [ - #metadata((t: "SaveSlide")) -] +#let save-slide = { + pdfpc_metadata.display(m=>set_or_fail("savedSlide", int(m.pages.last().label)-1)) +} -#let hidden-slide = [ - #metadata((t: "HiddenSlide")) -] +#let hidden-slide = { + pdfpc_metadata.update(m=>{ + m.pages.last().hidden=true; + m + }) +} #let config( duration-minutes: none, @@ -31,7 +72,7 @@ default-transition: none, ) = { if duration-minutes != none { - [ #metadata((t: "Duration", v: duration-minutes)) ] + set_or_fail("duration", duration-minutes); } let _time-config(time, msg-name, tag-name) = { @@ -42,27 +83,26 @@ } else { panic(msg-name + " must be either a datetime or a string in the HH:MM format.") } - - [ #metadata((t: tag-name, v: time)) ] + set_or_fail(tag-name, time); } if start-time != none { - _time-config(start-time, "Start time", "StartTime") + _time-config(start-time, "Start time", "startTime") } if end-time != none { - _time-config(end-time, "End time", "EndTime") + _time-config(end-time, "End time", "endTime") } if last-minutes != none { - [ #metadata((t: "LastMinutes", v: last_minutes)) ] + set_or_fail("lastMinutes", last_minutes); } if note-font-size != none { - [ #metadata((t: "NoteFontSize", v: note-font-size)) ] + set_or_fail("noteFontSize", note-font-size); } - [ #metadata((t: "DisableMarkdown", v: disable-markdown)) ] + set_or_fail("disableMarkdown", disable-markdown); if default-transition != none { let dir-to-angle(dir) = if dir == ltr { @@ -89,6 +129,6 @@ default-transition.at("direction", default: "outward") ) - [ #metadata((t: "DefaultTransition", v: transition-str)) ] + set_or_fail("defaultTransition", transition-str); } }