/*************************************************************** * A polylux theme by martino barbieri (https://mbarbieri.it) * * https://gitlab.com/martino.barbieri/polylux-sns-template/ * * Patched for the PhD defence of Jean-Marie Mineau * * LICENSE: MIT-0 * ***************************************************************/ #import "@preview/polylux:0.4.0" as pl: * /* PER TEMPLATE SNS */ // Background and decorations #let sns-polylux-template_sns-colormap = ( rgb("#00728D"), rgb("#183F56"), rgb("#4D4E4F"), rgb("#AB3502"), rgb("#E69426"), rgb("#9CD7F3"), ) /* PER TEMPLATE UNIPI */ #let sns-polylux-template_unipi-colormap = ( cmyk(100%,57%,0%,9%), cmyk(100%,57%,0%,38%), rgb("#444444"), rgb("#AB3502"), rgb("#E69426"), cmyk(25%,7%,0%,0%), ) #let sns-polylux-template_colormap = state("colormap", none) // Text and Fonts #let sns-polylux-template_text-font = state("txt-font", none) #let sns-polylux-template_title-font = state("title-font", none) #let sns-polylux-template_background-color = state("bkg_color1", none) #let sns-polylux-template_main-text-color = state("txt_color1", none) #let sns-polylux-template_second-text-color = state("txt_color2", none) #let sns-polylux-template_title-text-color = state("title_color", none) #let sns-polylux-template_size = state("size", none) #let sns-polylux-template_section-size = state("section-size",none) #let sns-polylux-template_title-size = state("title-size", none) // Data #let sns-polylux-template_title = state("title", none) #let sns-polylux-template_subtitle = state("subtitle", none) #let sns-polylux-template_footer-text = state("footer-text", none) #let sns-polylux-template_short-event = state("short-event", none) #let sns-polylux-template_authors = state("authors", none) #let sns-polylux-template_logo-1 = state("logo-1", none) #let sns-polylux-template_logo-2 = state("logo-2", none) #let sns-polylux-template_date = state("date", none) #let sns-polylux-template_section-pages = state("section-pages", ("plop": 0)) #let sns-polylux-template_slide-pages = state("slide-pages", 0) // Init #let sns-polylux-template( // General parameters aspect-ratio : "16-9", txt-font : ("Roboto", "Fira Sans", "DejaVu Sans"), title-font : ("Raleway", "PT Sans", "DejaVu Sans"), txt-color1 : black, txt-color2 : white, title-color : rgb("#444444"), size : 20pt, section-size : 20pt, title-size : 64pt, bkgnd-color : white, colormap : sns-polylux-template_sns-colormap, // Data title : none, subtitle : none, footer-text : none, short-event : none, logo-2 : none, logo-1 : none, authors : none, date : none, // Stuff body ) = { sns-polylux-template_text-font.update(txt-font) sns-polylux-template_title-font.update(title-font) sns-polylux-template_background-color.update(bkgnd-color) sns-polylux-template_main-text-color.update(txt-color1) sns-polylux-template_second-text-color.update(txt-color2) sns-polylux-template_title-text-color.update(title-color) sns-polylux-template_size.update(size) sns-polylux-template_title-size.update(title-size) sns-polylux-template_section-size.update(section-size) sns-polylux-template_colormap.update(colormap) set page( paper : "presentation-" + aspect-ratio, fill : bkgnd-color, margin : 0pt, header : none, footer : none, header-ascent : 0pt, footer-descent : 0pt, ) set text( fill : txt-color1, size : size, font : txt-font, ) sns-polylux-template_title.update(title) sns-polylux-template_subtitle.update(subtitle) if footer-text != none { sns-polylux-template_footer-text.update(footer-text) } sns-polylux-template_logo-2.update(logo-2) sns-polylux-template_logo-1.update(logo-1) sns-polylux-template_authors.update(authors) sns-polylux-template_date.update(date) body context { //let section-pages = sns-polylux-template_section-pages.final() if not "END" in sns-polylux-template_section-pages.at(here()).keys() { let page_num = counter("logical-slide").get() sns-polylux-template_section-pages.update(secpages => { secpages.insert("END", page_num) secpages }) } } } #let register-section(title, no_dedicated_slide: false) = context { // YUCKKKKK, but polylux don't allows access to integers soooooo let page_num = counter("logical-slide").get() //sns-polylux-template_slide-pages.at(here()) if no_dedicated_slide { page_num.at(0) += 1 } sns-polylux-template_section-pages.update(secpages => { secpages.insert(repr(title), page_num) secpages }) pl.toolbox.register-section(title) } #let progress-bar() = pl.toolbox.progress-ratio( ratio => { let colormap = sns-polylux-template_colormap.at(here()) let height = 3pt stack(dir: ltr, rect(width: ratio * 100%, height: height, fill: colormap.at(5)), rect(width: (1-ratio) * 100%, height: height, fill: colormap.at(0)), ) }) // Slides #let title-slide( body : none, logo : none, background : [], foreground : [], ) = context( { let content = align(top + center, context( { let title = sns-polylux-template_title.at(here()) let subtitle = sns-polylux-template_subtitle.at(here()) let authors = sns-polylux-template_authors.at(here()) let title-size = sns-polylux-template_title-size.at(here()) let logo = { if logo == none { sns-polylux-template_logo-1.at(here()) } else { logo } } let date = sns-polylux-template_date.at(here()) // Background place( bottom + right, polygon( fill : sns-polylux-template_colormap.at(here()).at(2), stroke : none, (0%, 42%),(100%, 42%),(100%, 0%), ), ) place( bottom + right, polygon( fill : sns-polylux-template_colormap.at(here()).at(1), stroke : none, (0%, 29%),(0%, 37%),(100%, 37%),(100%, 0%), ), ) place( bottom + right, polygon( fill : sns-polylux-template_colormap.at(here()).at(0), stroke : none, (0%, 20%),(0%, 30%),(100%, 30%),(100%, 0%), ), ) place( top + left, polygon( fill : sns-polylux-template_colormap.at(here()).at(2), stroke : none, (0%, 0%),(0%, 16%),(75%, 0%), ), ) place( top + left, polygon( fill : sns-polylux-template_colormap.at(here()).at(0), stroke : none, (0%, 0%),(0%, 15%),(75%, 0%), ), ) if logo != none { place( bottom + right, dx: -0.5cm, dy: -0.3cm, scale(page.height/measure(logo).height*22%, reflow: true, logo) ) } // Contents set align(center+top) v(17%) text( font : sns-polylux-template_title-font.at(here()), size : title-size, fill: sns-polylux-template_title-text-color.at(here()), weight: "bold", title ) linebreak() v(0em) text( font : sns-polylux-template_title-font.at(here()), size : 22pt, fill: sns-polylux-template_title-text-color.at(here()), subtitle ) //v(-0.9em) line(length: 90%, stroke: (paint: sns-polylux-template_colormap.at(here()).at(5), thickness: 4pt, cap: "round")) v(1em) set text( size: 24pt, top-edge: 0pt, bottom-edge: 0pt, fill: sns-polylux-template_main-text-color.at(here()) ) { set align(left) for i in range(authors.len()) { h(1em) authors.at(i) v(0.5em) //move(dx: 2% * ( i - ( authors.len() - 1 ) / 2 ), authors.at(i)) } if date != none { v(1em) h(1em) date.display() } } body } )) set page(background: background, foreground: foreground) pl.slide({ content }) counter("logical-slide").update( n => n - 1 ) } ) #let sections(pos_before_slide) = context { let section-pages = sns-polylux-template_section-pages.final() let section-size = sns-polylux-template_section-size.at(pos_before_slide) set text(size: section-size) let pnum = counter("logical-slide").at(pos_before_slide).first() + 1 pl.toolbox.all-sections((sections, current) => { let beg-end-section = (:) let prev-sec = none for section in sections { let s = repr(section.at("body")) if prev-sec != none { beg-end-section.insert(prev-sec, (section-pages.at(prev-sec).first(), section-pages.at(s).first())) } prev-sec = s } if prev-sec != none { beg-end-section.insert(prev-sec, (section-pages.at(prev-sec).first(), section-pages.at("END").first() + 1)) } let section_names = () let section_pages = () for s in sections { let pages = () let (pmin, pmax) = beg-end-section.at(repr(s.at("body"))) let p_i = pmin while p_i < pmax and p_i < pnum { // In section, before current page pages.push(sym.circle.filled) p_i += 1 } if p_i == pnum and p_i != pmax { // In section, current page pages.push(sym.ast.circle) p_i += 1 } while p_i < pmax { // In section, after current page pages.push(sym.circle.dotted) p_i += 1 } //section_names.push(scale(50%, reflow: true, [#pnum #s (#pmin, #pmax)])) if s == current { section_names.push(strong(s)) section_pages.push(strong(pages.join([]))) } else { section_names.push(s) section_pages.push(pages.join([])) } } grid( columns: (auto,)*section_names.len(), column-gutter: 1fr, row-gutter: 12pt, ..section_names, ..section_pages, ) }) } /* #let small-sections(show-sec-name: true) = context( { set text(bottom-edge: "descender") if show-sec-name {pl.toolbox.current-section;" "} pl.toolbox.all-sections( (sections, current) => { let over_current = false for i in sections { if current == i {$ast.circle$; over_current = true} else if (over_current or current not in sections) { $circle.dotted$ } else {$circle.filled$} } } ) } ) #let big-sections = context( { set align(horizon + right) grid( box(height: 40%, inset: 0.8cm)[#small-sections(show-sec-name: false)], box(height: 60%, inset: 0.8cm)[ #pl.toolbox.current-section ]) } ) */ #let slide( title : none, subtitle : none, new-sec : false, page-number : true, hide-section : false, hide-title : false, background : [], foreground : [], body ) = context( { let sections_height = 1.5cm let progress_bar_height = 3pt let title_bar_height = 2cm let pos_before_slide = here() // HEADER let header = align(top, context( { let logo = sns-polylux-template_logo-2.at(here()) // If new-sec is false, do nothing // If new-sec is true, new section's name is the slide title // Else the new-sec name is new-sec if type(new-sec)==bool { if new-sec { register-section(title, no_dedicated_slide: true) } } else { register-section(new-sec) } place(top + left, { let columns = if logo != none { (auto, 1fr,) } else { (1fr,) }; grid( columns: columns, gutter: 0pt, if logo != none { pad(logo, x: 0.3cm, top: 0.2cm) } else { [] }, rect( width: 100%, height: sections_height, inset: 0.8cm, outset: 0pt, fill: sns-polylux-template_colormap.at(here()).at(1), align(horizon + center,text(fill: sns-polylux-template_second-text-color.at(here()), { v(-1em) if hide-section { hide(sections(pos_before_slide)) } else { sections(pos_before_slide) } })) ), grid.cell(colspan: columns.len(), progress-bar()), if title != none and not hide-title { rect( width: 100%, height: title_bar_height, inset: 0.8cm, outset: 0pt, fill: sns-polylux-template_colormap.at(here()).at(0), align(horizon + center, { text( fill: sns-polylux-template_second-text-color.at(here()), font: sns-polylux-template_title-font.at(here()), size: 32pt, weight: "bold", title ) if subtitle != none { smallcaps(text( fill: sns-polylux-template_second-text-color.at(here()), font: sns-polylux-template_title-font.at(here()), size: 24pt, " — " + subtitle )) } }) ) } else { [] } ) }) // closes `place(top+left, {` } )) // closes `let header = ...` // FOOTER let footer = align(top + center, context( { let footer-text = sns-polylux-template_footer-text.at(here()) place(top + center, line(length: 100%-2cm, stroke: (paint: sns-polylux-template_colormap.at(here()).at(1), thickness: 2pt, cap: "round"))) set text(bottom-edge: "descender") block( height: 100%, width: 100%, inset: (x: 0.8cm), align(horizon,text(fill: sns-polylux-template_colormap.at(here()).at(2), size: 16pt, grid( gutter: 0.8cm, columns: (1fr, 5em), align(center, smallcaps(footer-text)), align(right, if page-number [#toolbox.slide-number/#toolbox.last-slide-number]), )) )) } )) let top-margin = if title != none { sections_height + progress_bar_height + title_bar_height } else { sections_height + progress_bar_height }; set page( margin: (top: top-margin, bottom: 1cm), header: header, footer: footer, background: background, foreground: foreground ) pl.slide({ set align(horizon) set text(size: sns-polylux-template_size.at(here()), top-edge: 20pt, bottom-edge: 0pt) show: block.with(inset: (x: 1.2cm, y:.2cm), width: 100%) body }) if not page-number { counter("logical-slide").update( n => n - 1 ) } } ) #let focus-slide( new-sec : none, page-number : true, hide-section : false, background : [], foreground : [], body ) = context( { set page( margin: (top: 2.5cm, bottom: 0cm), footer: none, fill: sns-polylux-template_colormap.at(here()).at(1), background: background, foreground: foreground ) pl.slide({ set align(horizon + center) set text( size: sns-polylux-template_size.at(here())*1.5, fill: sns-polylux-template_second-text-color.at(here()), style: "italic" ) show: block.with(inset: (x: 1.2cm, y:.2cm), width: 100%) body }) if not page-number { counter("logical-slide").update( n => n - 1 ) } } ) #let empty-slide( background : [], foreground : [], body ) = context( { // HEADER let header = align(top, context( { let logo = sns-polylux-template_logo-1.at(here()) place( top + left, box( height: 2.5cm, if logo != none { pad(logo, x: 0.3cm, top: 0.2cm) } ) ) } )) set page( margin: (top: 2.7cm, bottom: 0cm), header: header, footer: none, fill: sns-polylux-template_colormap.at(here()).at(1), background: background, foreground: foreground ) pl.slide({ set align(horizon + center) set text( size: sns-polylux-template_size.at(here())*1.5, fill: sns-polylux-template_second-text-color.at(here()), ) show: block.with(inset: (x: 1.2cm, y:.2cm), width: 100%) body }) counter("logical-slide").update( n => n - 1 ) } ) #let new-section-slide( name, background : [], foreground : [], ) = context( { // HEADER let header = align(top, context( { let logo = sns-polylux-template_logo-1.at(here()) place( top + left, box( height: 2.5cm, if logo != none { pad(logo, x: 0.3cm, top: 0.2cm) } ) ) } )) set page( margin: (top: 2.7cm, bottom: 0cm), header: header, footer: none, fill: sns-polylux-template_colormap.at(here()).at(1), background: background, foreground: foreground ) // TOC /* let content = context( { pl.toolbox.all-sections( (sections, current) => { set text(weight: "regular") let over_current = false for i in sections { if (current == i) {[ + #text(weight: "black", i) ]; over_current = true} else if (over_current) [ + #text(weight: "thin", i) ] else [ + #text(i) ] } } ) } ) */ pl.slide({ set align(horizon + center) set text( size: sns-polylux-template_size.at(here())*1.5, fill: sns-polylux-template_second-text-color.at(here()), ) register-section(name) show: pad.with(20%) name progress-bar() }) counter("logical-slide").update( n => n - 1 ) } ) #let toc-slide( title : none, background : [], foreground : [], ) = context( { // HEADER let header = align(top, { let logo = sns-polylux-template_logo-1.at(here()) place( top + left, box( height: 2.5cm, if logo != none { pad(logo, x: 0.3cm, top: 0.2cm) } ) ) } ) set page( margin: (top: 2.7cm, bottom: 0cm), header: header, footer: none, fill: sns-polylux-template_colormap.at(here()).at(1), background: background, foreground: foreground ) // TOC let content = { if title != none { align(center,text(weight: "bold", title)); v(-0.2em) } pl.toolbox.all-sections( (sections, current) => { for i in sections [ + #text(i) ] } ) } pl.slide({ set align(horizon + center) set text( size: sns-polylux-template_size.at(here())*1.5, fill: sns-polylux-template_second-text-color.at(here()), ) show: box.with() set align(left) content }) counter("logical-slide").update( n => n - 1 ) } )