release 1.0.1
- Show more options in the default template - Fix README visualization in typst universe
This commit is contained in:
parent
5915ed389e
commit
9b6fd2ed04
9 changed files with 1018 additions and 0 deletions
66
1.0.1/README.md
Normal file
66
1.0.1/README.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Typst ISEC Slides Template
|
||||
|
||||
An opinionated version of the ISEC slides template made in Typst. Easily configurable for other institutes or organizations.
|
||||
|
||||
Author: Ernesto Martínez García <[ecomaikgolf.com](https://ecomaikgolf.com)>
|
||||
|
||||
Tested typst version: `0.13.1`.
|
||||
|
||||
> [!NOTE]
|
||||
> If you are an ISEC or TUGraz employee and think that `isec-slides` or
|
||||
> `tugraz-slieds` fits more, I would need an approval to allocate the name :)
|
||||
|
||||
Need a thesis? Check out the sibling package [definitely-not-isec-thesis](https://typst.app/universe/package/definitely-not-isec-thesis)
|
||||
|
||||
## Contributing
|
||||
|
||||
Contribute to the template in the [upstream repository](https://github.com/ecomaikgolf/typst-isec-slides-template)
|
||||
|
||||
Check for [open issues](https://github.com/ecomaikgolf/typst-isec-slides-template/issues)
|
||||
|
||||
## Design
|
||||
---
|
||||

|
||||
|
||||
---
|
||||

|
||||
|
||||
---
|
||||

|
||||
|
||||
---
|
||||

|
||||
|
||||
---
|
||||

|
||||
|
||||
---
|
||||
![features]https://github.com/user-attachments/assets/1f3cd158-3860-4962-9802-7fc22d4b94a1)
|
||||
|
||||
---
|
||||

|
||||
|
||||
---
|
||||

|
||||
|
||||
---
|
||||

|
||||
|
||||
---
|
||||

|
||||
|
||||
---
|
||||

|
||||
|
||||
---
|
||||

|
||||
|
||||
## License `src/assets/tuglogo.svg`
|
||||
|
||||
According to Wikipedia:
|
||||
|
||||
> This logo image consists only of simple geometric shapes or text. It does not
|
||||
> meet the threshold of originality needed for copyright protection, and is
|
||||
> therefore in the public domain. [...]
|
||||
|
||||
https://en.m.wikipedia.org/wiki/File:TU_Graz.svg
|
||||
47
1.0.1/src/assets/tuglogo.svg
Normal file
47
1.0.1/src/assets/tuglogo.svg
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
version="1.0"
|
||||
width="800"
|
||||
height="400"
|
||||
id="svg2"
|
||||
sodipodi:docname="tuglogo.svg"
|
||||
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:zoom="0.74125"
|
||||
inkscape:cx="400"
|
||||
inkscape:cy="200.33727"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1080"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" />
|
||||
<defs
|
||||
id="defs4" />
|
||||
<path
|
||||
d="M 587.48841,328.23036 C 583.73744,330.20802 579.84328,331.69127 575.8059,332.68009 C 571.76841,333.66892 567.60074,334.16333 563.30287,334.16333 C 553.58695,334.16333 545.88978,331.21804 540.21134,325.32745 C 534.53287,319.43688 531.69365,311.44857 531.69365,301.36251 C 531.69365,291.1635 534.58497,283.13988 540.36762,277.29162 C 546.15025,271.44347 554.06883,268.51937 564.12337,268.51931 C 568.00448,268.51937 571.72283,268.9149 575.27842,269.7059 C 578.83391,270.49702 582.18759,271.66949 585.33945,273.2233 L 585.33945,286.3182 C 582.0834,284.31234 578.84694,282.81497 575.63006,281.8261 C 572.4131,280.83733 569.18966,280.34291 565.95975,280.34286 C 559.96869,280.34291 555.3517,282.15811 552.10875,285.78848 C 548.86576,289.41893 547.24427,294.61027 547.24429,301.36251 C 547.24427,308.05831 548.80715,313.22846 551.93293,316.87297 C 555.05866,320.51752 559.49983,322.33979 565.25646,322.33978 C 566.8193,322.33979 568.27147,322.23384 569.61299,322.02194 C 570.95441,321.81006 572.15913,321.4781 573.22714,321.02605 L 573.22714,308.73634 L 564.04524,308.73634 L 564.04524,297.80273 L 587.48841,297.80273 L 587.48841,328.23036 z M 632.57745,298.39603 C 631.35316,297.77451 630.13541,297.31542 628.92422,297.01873 C 627.71295,296.72212 626.49522,296.57379 625.27099,296.57376 C 621.67635,296.57379 618.90875,297.82395 616.9682,300.32424 C 615.02761,302.82459 614.05732,306.40555 614.05734,311.06714 L 614.05734,332.93436 L 600.06958,332.93436 L 600.06958,285.47064 L 614.05734,285.47064 L 614.05734,293.26825 C 615.85463,290.16055 617.91893,287.89331 620.25025,286.46653 C 622.58151,285.03983 625.37515,284.32647 628.63118,284.32642 C 629.10001,284.32647 629.60795,284.34766 630.15499,284.38999 C 630.70195,284.43242 631.49643,284.52423 632.53837,284.66545 L 632.57745,298.39603 z M 659.22453,311.57568 C 656.30714,311.57571 654.11259,312.11249 652.64091,313.18606 C 651.16918,314.25966 650.43332,315.84179 650.43334,317.93243 C 650.43332,319.8536 651.02591,321.35802 652.21112,322.44572 C 653.39628,323.53344 655.04381,324.0773 657.15372,324.07729 C 659.78453,324.0773 661.99861,323.05316 663.79596,321.00486 C 665.59323,318.95659 666.49188,316.3927 666.49191,313.3132 L 666.49191,311.57568 L 659.22453,311.57568 z M 680.59689,305.85461 L 680.59689,332.93436 L 666.49191,332.93436 L 666.49191,325.89956 C 664.61643,328.78129 662.50654,330.87902 660.16226,332.19274 C 657.81792,333.50646 654.96566,334.16333 651.60549,334.16333 C 647.07313,334.16333 643.39386,332.72953 640.56767,329.86193 C 637.74146,326.99434 636.32836,323.27211 636.32836,318.69524 C 636.32836,313.12958 638.09311,309.04714 641.62261,306.4479 C 645.1521,303.84873 650.6938,302.54913 658.24773,302.5491 L 666.49191,302.5491 L 666.49191,301.36251 C 666.49188,298.96111 665.61927,297.20241 663.87409,296.08641 C 662.12885,294.97048 659.40684,294.4125 655.70805,294.41246 C 652.71252,294.4125 649.92539,294.7374 647.34665,295.38716 C 644.76789,296.037 642.37149,297.0117 640.15741,298.31127 L 640.15741,286.74198 C 643.15293,285.95097 646.16146,285.35061 649.18304,284.94091 C 652.20459,284.5313 655.22614,284.32647 658.24773,284.32642 C 666.14024,284.32647 671.83823,286.01454 675.34171,289.39063 C 678.84512,292.76681 680.59685,298.2548 680.59689,305.85461 L 680.59689,305.85461 z M 691.53705,285.47064 L 729.71034,285.47064 L 729.71034,296.06521 L 706.65789,322.08551 L 729.71034,322.08551 L 729.71034,332.93436 L 690.56025,332.93436 L 690.56025,322.33978 L 713.6127,296.31949 L 691.53705,296.31949 L 691.53705,285.47064 z"
|
||||
id="text2424"
|
||||
style="font-size:110.52407074px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold" />
|
||||
<path
|
||||
d="M 530.95111,260.14746 L 530.95111,146.35144 L 489.77639,146.35144 L 489.77639,123.18115 L 600.04894,123.18115 L 600.04894,146.35144 L 558.96886,146.35144 L 558.96886,260.14746 L 530.95111,260.14746 z M 618.03331,123.18115 L 646.05104,123.18115 L 646.05104,197.36345 C 646.051,209.13551 646.39807,216.7655 647.09224,220.25346 C 648.29116,225.8592 651.14657,230.35934 655.65848,233.75388 C 660.17029,237.14848 666.33861,238.84576 674.16345,238.84574 C 682.11435,238.84576 688.10913,237.24191 692.14781,234.03417 C 696.18631,230.82649 698.61577,226.88692 699.43621,222.21545 C 700.25645,217.54407 700.66662,209.7895 700.66671,198.95174 L 700.66671,123.18115 L 728.68447,123.18115 L 728.68447,195.12116 C 728.68434,211.56464 727.92711,223.18092 726.41276,229.97003 C 724.89816,236.7592 722.10586,242.48947 718.03583,247.16089 C 713.96557,251.83232 708.52294,255.5539 701.70792,258.3256 C 694.8927,261.09732 685.99519,262.48317 675.01534,262.48318 C 661.76364,262.48317 651.71449,260.97274 644.86786,257.95189 C 638.02115,254.93104 632.61008,251.00704 628.63461,246.17989 C 624.6591,241.35277 622.04032,236.29205 620.77828,230.99774 C 618.94828,223.14978 618.03328,211.56464 618.03331,196.24231 L 618.03331,123.18115 z"
|
||||
id="text2428"
|
||||
style="font-size:255.42478943px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Arial;-inkscape-font-specification:Arial Bold" />
|
||||
<path
|
||||
d="M 261.48597,49.44316 L 261.48597,120.65005 L 176.35344,120.65005 L 176.35344,191.88051 L 162.07436,191.88051 L 162.07436,120.65005 L 21.168588,120.65005 L 21.168588,261.55582 L 92.399046,261.55582 L 92.399046,332.78628 L 233.30481,332.78628 L 233.30481,261.55582 L 317.2592,261.55582 L 317.2592,190.34893 L 331.56184,190.34893 L 331.56184,261.55582 L 472.46761,261.55582 L 472.46761,120.65005 L 402.39173,120.65005 L 402.39173,49.44316 L 261.48597,49.44316 z M 740.18857,284.41177 L 740.18857,333.16328 L 788.94007,333.16328 L 788.94007,284.41177 L 740.18857,284.41177 z"
|
||||
id="rect2432"
|
||||
style="opacity:0.97000002;fill:#f70146;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.2 KiB |
59
1.0.1/src/helper.typ
Normal file
59
1.0.1/src/helper.typ
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// --------------------------------------------------------------------------
|
||||
// Extra helper functions
|
||||
|
||||
// Fix for typst #311 "Behavior of first line indentation in paragraphs ..."
|
||||
// https://github.com/typst/typst/issues/311#issuecomment-2023038611
|
||||
// https://forum.typst.app/t/how-to-indent-paragraphs-following-a-list-without-affecting-the-paragraph-after-a-heading/4210?u=fungai2000
|
||||
#let fix-311 = context {
|
||||
set par.line(numbering: none)
|
||||
v(0pt, weak: true) + par(none)
|
||||
}
|
||||
|
||||
#let content-to-string(content) = {
|
||||
if content.has("text") {
|
||||
content.text
|
||||
}else if content.has("child") {
|
||||
content-to-string(content.child)
|
||||
} else if content.has("children") {
|
||||
content.children.map(content-to-string).join("")
|
||||
} else if content.has("body") {
|
||||
content-to-string(content.body)
|
||||
} else if content == [ ] {
|
||||
" "
|
||||
}
|
||||
}
|
||||
|
||||
#let content-to-string-omit(content) = {
|
||||
if content.has("text") {
|
||||
content.text
|
||||
}else if content.has("child") {
|
||||
content-to-string-omit(content.child)
|
||||
} else if content.has("children") {
|
||||
content.children.map(content-to-string-omit).join("")
|
||||
} else if content.has("body") {
|
||||
content-to-string-omit(content.body)
|
||||
} else if content == [ ] {
|
||||
" "
|
||||
} else {
|
||||
"..."
|
||||
}
|
||||
}
|
||||
|
||||
// partitle simulates \paragraph{title} (more or less)
|
||||
#let partitle(title: [Title], body) = context [
|
||||
#block(above: 0.8cm)[
|
||||
*#title.* #h(0.3cm) #body
|
||||
]
|
||||
#fix-311
|
||||
]
|
||||
|
||||
// Wrapper for the technique shown here:
|
||||
// https://typst.app/docs/reference/layout/layout/
|
||||
#let measure-text-height(body) = {
|
||||
layout(size => {
|
||||
let (height,) = measure(width: size.width, body)
|
||||
return height
|
||||
})
|
||||
}
|
||||
|
||||
//vim:tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab colorcolumn=81
|
||||
714
1.0.1/src/lib.typ
Normal file
714
1.0.1/src/lib.typ
Normal file
|
|
@ -0,0 +1,714 @@
|
|||
#import "@preview/touying:0.6.1": *
|
||||
|
||||
// Project
|
||||
#import "helper.typ": *
|
||||
#import "logos.typ": *
|
||||
|
||||
// Core Imports
|
||||
#import "@preview/codly:1.3.0": * // For bindings
|
||||
#import "@preview/cetz:0.4.1" // For bindings
|
||||
#import "@preview/fletcher:0.5.8" as fletcher: edge, node // For bindings
|
||||
#import "@preview/tiaoma:0.3.0" // For auto QR generation
|
||||
|
||||
// Styling Macro Imports
|
||||
#import "@preview/showybox:2.0.4": showybox
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// General Config
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Touying bindings for cetz
|
||||
#let cetz-canvas = touying-reducer.with(
|
||||
reduce: cetz.canvas,
|
||||
cover: cetz.draw.hide.with(bounds: true),
|
||||
)
|
||||
|
||||
// Touying bindings for fletcher
|
||||
#let fletcher-diagram = touying-reducer.with(
|
||||
reduce: fletcher.diagram,
|
||||
cover: fletcher.hide,
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Slide Types
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Normal slide for the presentation, with title (header) and footer
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```typst
|
||||
/// #slide(title: [Slide Title])[
|
||||
/// #lorem(20)
|
||||
/// ]
|
||||
/// ```
|
||||
///
|
||||
/// - title (content): Title for the slide
|
||||
/// - alignment (alignment): Alignment of the contents of the slide
|
||||
/// - outlined (boolean): If the slide shows on the PDF ToC
|
||||
///
|
||||
/// -> content
|
||||
#let slide(
|
||||
title: auto,
|
||||
alignment: none,
|
||||
outlined: true,
|
||||
..args,
|
||||
) = touying-slide-wrapper(self => {
|
||||
let info = self.info + args.named()
|
||||
|
||||
// Header:
|
||||
// ---------------------------------------------------------------------------
|
||||
// [ ] Slide Title [ ] Logo [ ]
|
||||
// ---------------------------------------------------------------------------
|
||||
let header(self) = {
|
||||
// Slide Title: if the user overrides the title of a certain slide, use it
|
||||
let hdr = if title != auto { title } else { self.store.header }
|
||||
|
||||
show heading: set text(size: 24pt, weight: "semibold")
|
||||
|
||||
grid(
|
||||
columns: (self.page.margin.left, 1fr, 1cm, auto, 1.2cm),
|
||||
block(),
|
||||
heading(level: 1, outlined: outlined, hdr),
|
||||
block(),
|
||||
move(dy: -0.31cm, institute-logo(self)),
|
||||
block(),
|
||||
)
|
||||
}
|
||||
|
||||
// Footer:
|
||||
// ---------------------------------------------------------------------------
|
||||
// Slide Number [ ] First Author
|
||||
// ---------------------------------------------------------------------------
|
||||
let footer(self) = context {
|
||||
set block(height: 100%, width: 100%)
|
||||
set text(size: 15pt, fill: self.colors.footer)
|
||||
|
||||
grid(
|
||||
columns: (self.page.margin.bottom - 1.68%, 1.3%, auto, 1cm),
|
||||
block(fill: self.colors.primary)[
|
||||
#set align(center + horizon)
|
||||
#set text(fill: white, size: 12pt)
|
||||
#utils.slide-counter.display()
|
||||
],
|
||||
block(),
|
||||
block[
|
||||
#set align(left + horizon)
|
||||
#set text(size: 13pt)
|
||||
#info.at("footer", default: "")
|
||||
],
|
||||
block(),
|
||||
)
|
||||
|
||||
// Progress bar
|
||||
if self.store.progress-bar {
|
||||
place(bottom + left, float: true,
|
||||
move(dy: 1.05cm, // Bad solution, I know
|
||||
components.progress-bar(
|
||||
height: 3pt,
|
||||
self.colors.primary,
|
||||
white,
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
let self = utils.merge-dicts(self, config-page(
|
||||
header: header,
|
||||
footer: footer,
|
||||
))
|
||||
|
||||
set align(
|
||||
if alignment == none {
|
||||
self.store.default-alignment
|
||||
} else {
|
||||
alignment
|
||||
}
|
||||
)
|
||||
|
||||
touying-slide(self: self, ..args)
|
||||
})
|
||||
|
||||
/// Title slide for the presentation
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```typst
|
||||
/// #title-slide()
|
||||
/// ```
|
||||
///
|
||||
/// -> content
|
||||
#let title-slide(..args) = touying-slide-wrapper(self => {
|
||||
let info = self.info + args.named()
|
||||
let body = {
|
||||
let footer-isec = [
|
||||
#set text(size: 13.3pt, weight: "medium")
|
||||
|
||||
#let arrow-icon = [
|
||||
#move(dy: -0.05cm, dx: -0.05cm, rotate(45deg, square(
|
||||
fill: none,
|
||||
size: 0.18cm,
|
||||
stroke: (
|
||||
"top": self.colors.primary + 1.35pt,
|
||||
"bottom": none,
|
||||
"right": self.colors.primary + 1.35pt,
|
||||
"left": none,
|
||||
),
|
||||
)))
|
||||
]
|
||||
|
||||
#v(-0.5cm)
|
||||
#box(arrow-icon) #h(0.1cm) #self.store.institute
|
||||
]
|
||||
|
||||
set page(footer: footer-isec, header: none)
|
||||
set block(below: 0pt, above: 0pt)
|
||||
|
||||
// Top-right icon + text
|
||||
place(top + right, dy: -1.9cm, dx: 0.78cm, [
|
||||
#self.store.logo
|
||||
])
|
||||
|
||||
v(0.8cm)
|
||||
|
||||
block(width: 83%)[
|
||||
#let title = text(size: 40.5pt, weight: "bold")[#info.at(
|
||||
"title",
|
||||
default: "",
|
||||
)]
|
||||
|
||||
#move(dx: 0.04em)[
|
||||
#grid(
|
||||
columns: (0.195cm, auto),
|
||||
column-gutter: 0.7cm,
|
||||
context [
|
||||
#let s = measure(title)
|
||||
#move(dy: -0.4cm, rect(
|
||||
fill: self.colors.primary,
|
||||
height: s.height + 0.65cm,
|
||||
))
|
||||
],
|
||||
title,
|
||||
)
|
||||
]
|
||||
]
|
||||
|
||||
v(0.6cm)
|
||||
|
||||
block(width: 70%)[
|
||||
#text(
|
||||
size: 28.3pt,
|
||||
fill: self.colors.primary,
|
||||
weight: "bold",
|
||||
)[#info.subtitle]
|
||||
]
|
||||
|
||||
v(1.48cm)
|
||||
|
||||
block(width: 70%)[
|
||||
#set text(size: 19pt)
|
||||
#if type(info.authors) == array [
|
||||
#for author in info.authors [
|
||||
#author #h(1.1em)
|
||||
]
|
||||
] else [
|
||||
#info.authors
|
||||
]
|
||||
]
|
||||
|
||||
v(0.95cm)
|
||||
|
||||
block(width: 70%)[
|
||||
#info.extra
|
||||
]
|
||||
|
||||
if (
|
||||
self.info.at("download-qr", default: none) != none
|
||||
and self.info.at("download-qr", default: none) != ""
|
||||
) {
|
||||
place(bottom + right)[
|
||||
#align(center + horizon)[
|
||||
#let s = 4.9cm
|
||||
#tiaoma.qrcode(self.info.download-qr, width: s, height: s)
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
touying-slide(self: self, body)
|
||||
})
|
||||
|
||||
/// Standout slide for the presentation
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```typst
|
||||
/// #standout-slide(title: [Text])
|
||||
/// ```
|
||||
///
|
||||
/// - title (content): Title for the standout slide
|
||||
///
|
||||
/// -> content
|
||||
#let standout-slide(
|
||||
title: none,
|
||||
..args,
|
||||
) = touying-slide-wrapper(self => {
|
||||
let body = {
|
||||
set align(center + horizon)
|
||||
set text(size: 28pt)
|
||||
if title != none {
|
||||
move(dy: -2.08cm)[
|
||||
#text(weight: "semibold")[#title]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
let self = utils.merge-dicts(self, config-page(
|
||||
header: none,
|
||||
footer: none,
|
||||
))
|
||||
|
||||
//counter("touying-slide-counter").update(n => if n > 0 { n - 1 } else { 0 })
|
||||
|
||||
touying-slide(self: self, body, ..args)
|
||||
})
|
||||
|
||||
/// Section slide for the presentation
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```typst
|
||||
/// #section-slide(title: [Section A], subtitle: [Subtitle])
|
||||
/// ```
|
||||
///
|
||||
/// - title (content): Title for the section
|
||||
/// - subtitle (content): Subtitle for the section
|
||||
///
|
||||
/// -> content
|
||||
#let section-slide(
|
||||
title: none,
|
||||
subtitle: none,
|
||||
..args,
|
||||
) = touying-slide-wrapper(self => {
|
||||
let body = {
|
||||
align(center + horizon)[
|
||||
#move(dy: -0.4cm)[
|
||||
#if title != none [
|
||||
#text(size: 36pt, weight: "semibold")[#title]
|
||||
]
|
||||
|
||||
#if subtitle != none [
|
||||
#text(size: 20pt)[#subtitle]
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
let self = utils.merge-dicts(self, config-page(
|
||||
header: none,
|
||||
footer: none,
|
||||
))
|
||||
|
||||
touying-slide(self: self, body, ..args)
|
||||
})
|
||||
|
||||
/// Blank slide for free content in the presentation
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```typst
|
||||
/// #blank-slide[
|
||||
/// #align(center + horizon)[#lorem(5)]
|
||||
/// ]
|
||||
/// ```
|
||||
///
|
||||
/// -> content
|
||||
#let blank-slide(
|
||||
..args,
|
||||
body,
|
||||
) = touying-slide-wrapper(self => {
|
||||
let body = {
|
||||
align(center + horizon)[
|
||||
#body
|
||||
]
|
||||
}
|
||||
|
||||
let self = utils.merge-dicts(self, config-page(
|
||||
header: none,
|
||||
footer: none,
|
||||
margin: 0pt,
|
||||
))
|
||||
|
||||
touying-slide(self: self, body, ..args)
|
||||
})
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Main Function
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Theme cofniguration
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```typst
|
||||
/// #show: definitely-not-isec-theme.with(
|
||||
/// aspect-ratio: "16-9",
|
||||
/// slide-alignment: top,
|
||||
/// config-info(
|
||||
/// title: [Long Paper Title \ with One to Three Lines],
|
||||
/// subtitle: [An optional short subtitle],
|
||||
/// authors: ([*First Author*], [Second Author], [Third Author]),
|
||||
/// extra: [SomeConf 2025],
|
||||
/// footer: [First Author, Second Author, Third Author],
|
||||
/// download-qr: "",
|
||||
/// ),
|
||||
/// config-common(
|
||||
/// handout: false,
|
||||
/// ),
|
||||
/// config-colors(
|
||||
/// ),
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// - aspect-ratio (str): Aspect ratio for the page. See typst documentatin.
|
||||
/// - slide-alignemnt (alignment): Default alignment for `#slide()`
|
||||
/// - config-info (dict):
|
||||
/// - title (content): Title for the presentation
|
||||
/// - subtitle (content): Subtitle for the presentation
|
||||
/// - authors (array): Arrray of authors (content)
|
||||
/// - extra (content): Extra information for the presentation
|
||||
/// - footer (content): Footer for each `#slide()`
|
||||
/// - download-qr (str): URL to show on `#title-slide()` with a QR
|
||||
/// - config-common (dict):
|
||||
/// - handout (bool): Boolean for handout mode
|
||||
/// - config-colors (dict): Colors for the presentation
|
||||
/// - ... see definition of `#definitely-not-isec-theme`
|
||||
#let definitely-not-isec-theme(
|
||||
aspect-ratio: "16-9",
|
||||
header: utils.display-current-heading(level: 1),
|
||||
font: "Open Sans",
|
||||
institute: [isec.tugraz.at],
|
||||
logo: tugraz-logo,
|
||||
slide-alignment: top,
|
||||
progress-bar: true,
|
||||
..args,
|
||||
body,
|
||||
) = {
|
||||
// Touying configuration
|
||||
show: touying-slides.with(
|
||||
config-page(
|
||||
paper: "presentation-" + aspect-ratio,
|
||||
margin: (
|
||||
left: 1.49cm,
|
||||
right: 1.48cm,
|
||||
top: 2.6cm,
|
||||
bottom: 1.6cm,
|
||||
)
|
||||
),
|
||||
config-store(
|
||||
header: header,
|
||||
font: font,
|
||||
institute: institute,
|
||||
logo: logo,
|
||||
default-alignment: slide-alignment,
|
||||
progress-bar: progress-bar,
|
||||
),
|
||||
config-common(
|
||||
slide-fn: slide,
|
||||
new-section-slide-fn: none,
|
||||
preamble: {
|
||||
codly(
|
||||
display-name: false,
|
||||
display-icon: false,
|
||||
radius: 0pt,
|
||||
stroke: 1pt + black,
|
||||
smart-indent: true,
|
||||
fill: luma(260),
|
||||
zebra-fill: luma(250),
|
||||
number-format: number => [#text(size: 12pt, fill: gray)[#number]],
|
||||
number-align: right + horizon,
|
||||
breakable: true,
|
||||
)
|
||||
}
|
||||
),
|
||||
config-colors( // Exported from official template
|
||||
tug: rgb("e4154b"),
|
||||
primary: rgb("e4154b"),
|
||||
footer: rgb("808080"),
|
||||
isec: rgb("272733"),
|
||||
foot: rgb("e1e1e1"),
|
||||
web: rgb("0c5a77"),
|
||||
csbme: rgb("19b4e3"),
|
||||
arch: rgb("0a98a2"),
|
||||
bauw: rgb("d68e23"),
|
||||
etec: rgb("68242c"),
|
||||
mach: rgb("3066ba"),
|
||||
chem: rgb("5e60a8"),
|
||||
math: rgb("1e6934"),
|
||||
crypto: rgb("a6c947"),
|
||||
system: rgb("1171a8"),
|
||||
formal: rgb("f7931e"),
|
||||
applied: rgb("7d219e"),
|
||||
page: rgb("e4154b"),
|
||||
fore: rgb("0f0f0f"),
|
||||
back: rgb("ffffff"),
|
||||
dark: rgb("3b5a70"),
|
||||
lite: rgb("eeece1"),
|
||||
head: rgb("245b78"),
|
||||
body: rgb("e2e9ed"),
|
||||
urlA: rgb("0066d8"),
|
||||
urlB: rgb("6c2f91"),
|
||||
colA: rgb("e4154b"),
|
||||
colB: rgb("5191c1"),
|
||||
colC: rgb("a5a5a5"),
|
||||
colD: rgb("285f82"),
|
||||
colE: rgb("78b473"),
|
||||
colF: rgb("e59352"),
|
||||
tugred: rgb("e4154b"),
|
||||
tuggreen: rgb("78b473"),
|
||||
tugblue: rgb("285f82"),
|
||||
tugyellow: rgb("e59352"),
|
||||
tugcyan: rgb("19b4e3"),
|
||||
tugpurple: rgb("7d219e"),
|
||||
tugviolet: rgb("5e60a8"),
|
||||
tugmagenta: rgb("7d219e"),
|
||||
tugturquoise: rgb("0a98a2"),
|
||||
tugbrown: rgb("68242c"),
|
||||
tugblack: rgb("0f0f0f"),
|
||||
tugwhite: rgb("ffffff"),
|
||||
tuggray: rgb("a5a5a5"),
|
||||
tuggrey: rgb("a5a5a5"),
|
||||
tugdark: rgb("3b5a70"),
|
||||
tugmid: rgb("5191c1"),
|
||||
tuglite: rgb("eeece1"),
|
||||
main: rgb("e4154b"),
|
||||
emph: rgb("285f82"),
|
||||
standout: rgb("245b78"),
|
||||
),
|
||||
config-methods(
|
||||
cover: (self: none, body) => hide(body),
|
||||
init: (
|
||||
self: none,
|
||||
body,
|
||||
) => {
|
||||
// TUGraz uses Source Sans Pro, but its a licensed Adobe font
|
||||
set text(size: 20pt, lang: "en", region: "US", font: font)
|
||||
show emph: it => { text(self.colors.primary, it.body) }
|
||||
show cite: it => { text(self.colors.primary, it) }
|
||||
show strong: it => { text(weight: "bold", it.body) }
|
||||
|
||||
// Bibliography
|
||||
set bibliography(title: none, style: "ieee")
|
||||
set cite(style: "alphanumeric")
|
||||
show bibliography: set par(spacing: 0.4cm)
|
||||
show bibliography: set grid(align: top + left)
|
||||
show bibliography: set text(17pt)
|
||||
show bibliography: t => {
|
||||
show grid.cell.where(x: 0): set text(fill: self.colors.primary)
|
||||
show grid.cell.where(x: 0): set align(top + left)
|
||||
show link: set text(fill: gray)
|
||||
t
|
||||
}
|
||||
|
||||
// Lists & Enums
|
||||
set list(
|
||||
marker: (
|
||||
(move(dy: 0.11cm, square(width: 0.4em, height: 0.4em, fill: self.colors.primary))),
|
||||
(move(dy: 0.11cm, square(width: 0.4em, height: 0.4em, fill: black))),
|
||||
(move(dy: 0.11cm, square(width: 0.4em, height: 0.4em, fill: gray))),
|
||||
),
|
||||
body-indent: 1.2em,
|
||||
)
|
||||
set enum(
|
||||
numbering: n => {
|
||||
square(stroke: none, fill: self.colors.primary, size: 0.53cm)[
|
||||
#align(center + horizon)[ #text(size: 12pt, fill: white)[#n] ]
|
||||
]
|
||||
},
|
||||
body-indent: 0.6cm
|
||||
)
|
||||
|
||||
// Code blocks
|
||||
show: codly-init.with()
|
||||
show raw.where(block: true): set text(size: 13pt)
|
||||
|
||||
// Hotfixes, the messy part
|
||||
|
||||
// https://github.com/touying-typ/touying/issues/136
|
||||
set par(spacing: 0.65em)
|
||||
|
||||
body
|
||||
}),
|
||||
..args,
|
||||
)
|
||||
|
||||
body
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Macros
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Macro for a pdfpc note
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```typst
|
||||
/// #note("This will show on pdfpc speaker notes")
|
||||
/// ```
|
||||
///
|
||||
/// - text (str): Note for pdfpc
|
||||
///
|
||||
/// -> content
|
||||
#let note(text) = [
|
||||
#pdfpc.speaker-note(text)
|
||||
]
|
||||
|
||||
/// Quote block for phrases. Has a color.primary rectangle in the left
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```typst
|
||||
/// #quote-block[
|
||||
/// #lorem(10)
|
||||
/// ]
|
||||
/// ```
|
||||
///
|
||||
/// - top-pad (length): Extra height of the quote colored block
|
||||
/// - color (color): Color of the quote block
|
||||
/// - spacing (length): Spacing after the `#quote-block`
|
||||
///
|
||||
/// -> content
|
||||
#let quote-block(
|
||||
top-pad: 0.55cm,
|
||||
color: none,
|
||||
spacing: 0.3cm,
|
||||
body,
|
||||
) = [
|
||||
#touying-fn-wrapper((self: none) => [
|
||||
// Grid with the design
|
||||
#let g(s: 0cm, body) = [
|
||||
#grid(
|
||||
columns: (0.195cm, auto),
|
||||
column-gutter: 0.7cm,
|
||||
row-gutter: 0cm,
|
||||
[
|
||||
#rect(
|
||||
fill: if color == none { self.colors.primary } else { color },
|
||||
height: s + top-pad,
|
||||
)
|
||||
],
|
||||
align(horizon, body),
|
||||
)
|
||||
]
|
||||
|
||||
// We compute its "auto" heigth and then print it with the correct height
|
||||
#layout(size => {
|
||||
let (height,) = measure(width: size.width, g(body))
|
||||
g(s: height, body)
|
||||
})
|
||||
|
||||
#v(spacing)
|
||||
])
|
||||
]
|
||||
|
||||
/// Block with title and content
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```typst
|
||||
/// #color-block(title: [Advantages])[
|
||||
/// - A
|
||||
/// - B
|
||||
/// - C
|
||||
/// ]
|
||||
/// ```
|
||||
///
|
||||
/// - title (content): Title for the color block
|
||||
/// - icon (str): Icon to show at the left of the title (Tableau Icons) https://tabler.io/icons
|
||||
/// - spacing (length): Spacing before and after the color block
|
||||
/// - color (color): Color for the title block
|
||||
/// - color-body (color): Color for the background of the body
|
||||
///
|
||||
/// -> content
|
||||
#let color-block(
|
||||
title: [],
|
||||
icon: none,
|
||||
spacing: 0.78em,
|
||||
color: none,
|
||||
color-body: none,
|
||||
body
|
||||
) = [
|
||||
#import "@preview/tableau-icons:0.331.0": *
|
||||
#touying-fn-wrapper((self: none) => [
|
||||
#show emph: it => {
|
||||
text(weight: "medium", fill: self.colors.primary, it.body)
|
||||
}
|
||||
|
||||
#showybox(
|
||||
title-style: (
|
||||
color: white,
|
||||
sep-thickness: 0pt,
|
||||
),
|
||||
frame: (
|
||||
//inset: 0.4em,
|
||||
radius: 0pt,
|
||||
thickness: 0pt,
|
||||
border-color: if color == none { self.colors.primary } else { color },
|
||||
title-color: if color == none { self.colors.primary } else { color },
|
||||
body-color: if color-body == none { self.colors.lite } else { color-body },
|
||||
inset: (x: 0.55em, y: 0.65em),
|
||||
),
|
||||
above: spacing,
|
||||
below: spacing,
|
||||
title: if icon == none {
|
||||
align(horizon)[#strong(title)]
|
||||
} else {
|
||||
align(horizon)[
|
||||
#draw-icon(icon, height: 1.2em, baseline: 20%, fill: white) #h(0.2cm) #strong[#title]
|
||||
]
|
||||
},
|
||||
body,
|
||||
)
|
||||
])
|
||||
]
|
||||
|
||||
/// Showcase the colors of the slide
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```typst
|
||||
/// #showcase-colors
|
||||
/// ```
|
||||
///
|
||||
/// -> content
|
||||
#let showcase-colors = [
|
||||
#touying-fn-wrapper((self: none) => [
|
||||
#set rect(width: 7.4cm, height: 1.5cm)
|
||||
#set text(fill: white)
|
||||
#set align(center)
|
||||
#grid(columns: 3, rows: 6, column-gutter: 1.8cm, row-gutter: 0.05cm, align: left,
|
||||
rect(fill: self.colors.isec)[isec],
|
||||
rect(fill: self.colors.tug)[tug = main],
|
||||
rect(fill: self.colors.colA)[colA = tugred],
|
||||
rect(fill: self.colors.csbme)[csbme = tugcyan],
|
||||
rect(fill: self.colors.fore)[fore],
|
||||
rect(fill: self.colors.colB)[colB = tugmid],
|
||||
rect(fill: self.colors.crypto)[crypto],
|
||||
rect(fill: self.colors.back)[#text(fill: black)[back]],
|
||||
rect(fill: self.colors.colC)[colC = tuggray],
|
||||
rect(fill: self.colors.system)[system],
|
||||
rect(fill: self.colors.foot)[#text(fill: black)[foot]],
|
||||
rect(fill: self.colors.colD)[colD = tugblue],
|
||||
rect(fill: self.colors.formal)[formal],
|
||||
rect(fill: self.colors.emph)[emph],
|
||||
rect(fill: self.colors.colE)[colE = tuggreen],
|
||||
rect(fill: self.colors.applied)[applied = tugpurple],
|
||||
rect(fill: self.colors.lite)[#text(fill: black)[lite]],
|
||||
rect(fill: self.colors.colF)[colF = tugyellow],
|
||||
)
|
||||
])
|
||||
]
|
||||
|
||||
//vim:tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab colorcolumn=81
|
||||
40
1.0.1/src/logos.typ
Normal file
40
1.0.1/src/logos.typ
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#let institute-logo(self) = [
|
||||
#block[
|
||||
#text(size: 13.5pt, weight: "medium")[#self.store.institute]
|
||||
#h(0.1cm)
|
||||
#box(inset: 0pt, outset: 0pt)[#square(
|
||||
width: 0.3cm,
|
||||
height: 0.3cm,
|
||||
outset: 0pt,
|
||||
inset: 0pt,
|
||||
stroke: none,
|
||||
fill: self.colors.primary,
|
||||
)]
|
||||
]
|
||||
]
|
||||
|
||||
#let tugraz-logo = [
|
||||
#set align(right)
|
||||
#set text(size: 12pt, tracking: 3.6pt)
|
||||
|
||||
#image("assets/tuglogo.svg", width: 4.1cm)
|
||||
|
||||
#v(0.13cm)
|
||||
|
||||
#move(dx: -0.07cm)[
|
||||
SCIENCE
|
||||
]
|
||||
|
||||
#v(0.65em)
|
||||
|
||||
#move(dx: -0.03cm)[
|
||||
PASSION
|
||||
]
|
||||
|
||||
#v(0.65em)
|
||||
|
||||
#move(dx: -0.06cm)[
|
||||
TECHNOLOGY
|
||||
]
|
||||
]
|
||||
|
||||
13
1.0.1/template/bibliography.bib
Normal file
13
1.0.1/template/bibliography.bib
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// You can use LaTeX's bibliography format per default
|
||||
// or
|
||||
// Typst's Hayagriva:
|
||||
// https://github.com/typst/hayagriva/blob/main/docs/file-format.md
|
||||
|
||||
@software{emg25template,
|
||||
author = {Ernesto Martínez García},
|
||||
year = {2025},
|
||||
month = {3},
|
||||
title = {{ISEC Slides Typst Template}},
|
||||
url = {https://github.com/ecomaikgolf/typst-isec-master-thesis-template},
|
||||
urldate = {2025-08-31}
|
||||
}
|
||||
62
1.0.1/template/slides.typ
Normal file
62
1.0.1/template/slides.typ
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#import "@preview/definitely-not-isec-slides:1.0.1": *
|
||||
|
||||
#show: definitely-not-isec-theme.with(
|
||||
aspect-ratio: "16-9",
|
||||
slide-alignment: top,
|
||||
progress-bar: true,
|
||||
institute: [isec.tugraz.at],
|
||||
logo: [#tugraz-logo],
|
||||
config-info(
|
||||
title: [Long Paper Title \ with One to Three Lines],
|
||||
subtitle: [An optional short subtitle],
|
||||
authors: ([*First Author*], [Second Author], [Third Author]),
|
||||
extra: [SomeConf 2025],
|
||||
footer: [First Author, Second Author, Third Author],
|
||||
download-qr: "",
|
||||
),
|
||||
config-common(
|
||||
handout: false,
|
||||
),
|
||||
config-colors(
|
||||
primary: rgb("e4154b"),
|
||||
),
|
||||
)
|
||||
|
||||
// -------------------------------[[ CUT HERE ]]--------------------------------
|
||||
//
|
||||
// === Available slides ===
|
||||
//
|
||||
// #title-slide()
|
||||
// #standout-slide(title)
|
||||
// #section-slide(title,subtitle)
|
||||
// #blank-slide()
|
||||
// #slide(title)
|
||||
//
|
||||
// === Available macros ===
|
||||
//
|
||||
// #quote-block(body)
|
||||
// #color-block(title, body)
|
||||
// #icon-block(title, icon, body)
|
||||
//
|
||||
// === Presenting with pdfpc ===
|
||||
//
|
||||
// Use #note("...") to add pdfpc presenter annotations on a specific slide
|
||||
// Before presenting, export all notes to a pdfpc file:
|
||||
// $ typst query slides.typ --field value --one "<pdfpc-file>" > slides.pdfpc
|
||||
// $ pdfpc slides.pdf
|
||||
//
|
||||
// -------------------------------[[ CUT HERE ]]--------------------------------
|
||||
|
||||
#title-slide()
|
||||
|
||||
#slide(title: [First Slide])[
|
||||
#quote-block[
|
||||
Good luck with your presentation! @emg25template
|
||||
]
|
||||
|
||||
#note("This will show on pdfpc speaker notes ;)")
|
||||
]
|
||||
|
||||
#slide(title: [Bibliography])[
|
||||
#bibliography("bibliography.bib")
|
||||
]
|
||||
BIN
1.0.1/thumbnail.png
Normal file
BIN
1.0.1/thumbnail.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
17
1.0.1/typst.toml
Normal file
17
1.0.1/typst.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "definitely-not-isec-slides"
|
||||
version = "1.0.1"
|
||||
entrypoint = "src/lib.typ"
|
||||
authors = ["Ernesto Martínez <https://ecomaikgolf.com>"]
|
||||
license = "MIT"
|
||||
description = "An unofficial ISEC TUGraz slides template"
|
||||
repository = "https://github.com/ecomaikgolf/typst-isec-slides-template"
|
||||
categories = ["presentation"]
|
||||
disciplines = ["computer-science", "engineering"]
|
||||
keywords = ["ISEC", "Institute of Information Security", "IAIK", "TUGraz", "Graz University of Technology", "thesis", "template", "Master Thesis"]
|
||||
compiler = "0.13.1"
|
||||
|
||||
[template]
|
||||
path = "template"
|
||||
entrypoint = "slides.typ"
|
||||
thumbnail = "thumbnail.png"
|
||||
Loading…
Add table
Add a link
Reference in a new issue