slidev-theme-tud 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.envrc +1 -0
- package/.github/workflows/deploy.yml +84 -0
- package/.github/workflows/release.yml +89 -0
- package/.vscode/extensions.json +3 -0
- package/README.md +60 -0
- package/assets/TUD-logo-bl.svg +1 -0
- package/assets/TUD-logo-no-color.svg +1 -0
- package/assets/TUD-logo-text-no-color.svg +1 -0
- package/assets/TUD-logo-text-small-no-color.svg +1 -0
- package/assets/TUD-logo-tr.svg +1 -0
- package/assets/favicons/apple-touch-icon.png +0 -0
- package/assets/favicons/dark/apple-touch-icon.png +0 -0
- package/assets/favicons/dark/favicon-16x16.png +0 -0
- package/assets/favicons/dark/favicon-32x32.png +0 -0
- package/assets/favicons/dark/favicon.ico +0 -0
- package/assets/favicons/favicon-16x16.png +0 -0
- package/assets/favicons/favicon-32x32.png +0 -0
- package/assets/favicons/favicon.ico +0 -0
- package/assets/fonts/FiraCode-VariableFont_wght.ttf +0 -0
- package/assets/fonts/NotoSans-Italic-VariableFont_wdth,wght.ttf +0 -0
- package/assets/fonts/NotoSans-VariableFont_wdth,wght.ttf +0 -0
- package/assets/fonts/OFL.txt +93 -0
- package/components/.gitkeep +0 -0
- package/components/Background.vue +130 -0
- package/components/Footnotes.vue +164 -0
- package/example.mdc +372 -0
- package/flake.lock +61 -0
- package/flake.nix +22 -0
- package/global-bottom.vue +79 -0
- package/global-top.vue +72 -0
- package/layouts/README.md +2 -0
- package/layouts/cols.vue +38 -0
- package/layouts/cover-blue.vue +60 -0
- package/layouts/cover-white.vue +58 -0
- package/layouts/cover.vue +10 -0
- package/layouts/default.vue +15 -0
- package/layouts/section-blue.vue +32 -0
- package/layouts/section-n.vue +171 -0
- package/layouts/section-white.vue +25 -0
- package/layouts/section.vue +10 -0
- package/markdown.ts +196 -0
- package/package.json +70 -0
- package/pnpm-workspace.yaml +23 -0
- package/scripts/background.ts +69 -0
- package/scripts/color.ts +81 -0
- package/scripts/util.ts +51 -0
- package/setup/katex.ts +35 -0
- package/setup/shiki.ts +48 -0
- package/shims.d.ts +27 -0
- package/styles/fade-transition.css +36 -0
- package/styles/font.css +28 -0
- package/styles/index.ts +5 -0
- package/styles/layout.css +184 -0
- package/tsconfig.json +30 -0
- package/uno.config.ts +35 -0
- package/vite.config.ts +29 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useSlideContext } from '@slidev/client'
|
|
3
|
+
import { computed, nextTick, onBeforeUnmount, onMounted, ref, unref, watch } from 'vue'
|
|
4
|
+
|
|
5
|
+
// Markdown footnotes are wrapped in this component by the footnote render-rule
|
|
6
|
+
// override in vite.config.ts. Instead of rendering inline at the bottom of the
|
|
7
|
+
// slide (where they get caught by slide transitions), we teleport them into a
|
|
8
|
+
// target in global-bottom.vue. That layer is rendered *outside* Slidev's
|
|
9
|
+
// transition group, so the footnotes no longer animate, and they sit right
|
|
10
|
+
// next to the footer for easy styling.
|
|
11
|
+
const { $nav, $page, $clicks } = useSlideContext()
|
|
12
|
+
|
|
13
|
+
// Each mounted slide (the active one, preloaded neighbours, every print page)
|
|
14
|
+
// renders its own <Footnotes>. Only the slide that is currently shown teleports
|
|
15
|
+
// into the shared target; the others render nothing (see v-if below) so they
|
|
16
|
+
// neither collide in the target nor flash their footnotes in-place while
|
|
17
|
+
// sliding out during a transition.
|
|
18
|
+
const isActive = computed(() => unref($page) === unref(($nav as any).value.currentPage))
|
|
19
|
+
|
|
20
|
+
// The target id is scoped to the page number. In print/export each page has
|
|
21
|
+
// its own global-bottom with a page-scoped nav, so this keeps every page's
|
|
22
|
+
// footnotes pointed at *its own* target instead of all resolving to the first.
|
|
23
|
+
const target = computed(() => `#footnotes-containter-${unref($page)}`)
|
|
24
|
+
|
|
25
|
+
// --- Footnote <-> reference visibility mirroring -----------------------------
|
|
26
|
+
// markdown-it-footnote already links each footnote to its in-text references:
|
|
27
|
+
// reference: <sup class="footnote-ref"><a href="#fnN" id="fnrefN[:k]">[N]</a>
|
|
28
|
+
// footnote: <li id="fnN" class="footnote-item">
|
|
29
|
+
// so a footnote `fnN` corresponds to every `.footnote-ref a[href="#fnN"]`.
|
|
30
|
+
//
|
|
31
|
+
// The references live in the slide body and may sit inside a `v-click` (or any
|
|
32
|
+
// other reveal), which fades them via opacity. Because the footnote block is
|
|
33
|
+
// teleported out of the slide it no longer shares that opacity, so on its own
|
|
34
|
+
// it would always be fully visible. We mirror it here: each footnote item takes
|
|
35
|
+
// the *max* opacity of its references (visible as soon as any one reference is),
|
|
36
|
+
// reading the live, mid-transition value so the footnote fades in lockstep.
|
|
37
|
+
|
|
38
|
+
// Hidden marker that stays in the (non-teleported) slide body, used purely to
|
|
39
|
+
// locate the slide root that contains this instance's references.
|
|
40
|
+
const anchorEl = ref<HTMLElement | null>(null)
|
|
41
|
+
// Wrapper around the teleported list; `display: contents` keeps it transparent
|
|
42
|
+
// to layout while giving us a handle on *this* instance's footnote items.
|
|
43
|
+
const listEl = ref<HTMLElement | null>(null)
|
|
44
|
+
let slideRoot: HTMLElement | null = null
|
|
45
|
+
|
|
46
|
+
// Cumulative (visible) opacity of `el` relative to `root`: the product of every
|
|
47
|
+
// opacity along the ancestor chain, so nested reveals compose correctly.
|
|
48
|
+
function visibleOpacity(el: HTMLElement, root: HTMLElement) {
|
|
49
|
+
let opacity = 1
|
|
50
|
+
let node: HTMLElement | null = el
|
|
51
|
+
while (node) {
|
|
52
|
+
opacity *= Number.parseFloat(getComputedStyle(node).opacity) || 0
|
|
53
|
+
if (node === root)
|
|
54
|
+
break
|
|
55
|
+
node = node.parentElement
|
|
56
|
+
}
|
|
57
|
+
return opacity
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Mirror every footnote item's opacity onto the max of its references' opacity.
|
|
61
|
+
// Returns whether anything changed this pass (used to detect a settled fade).
|
|
62
|
+
function syncOnce() {
|
|
63
|
+
const list = listEl.value
|
|
64
|
+
if (!slideRoot || !list)
|
|
65
|
+
return false
|
|
66
|
+
let changed = false
|
|
67
|
+
list.querySelectorAll<HTMLElement>('.footnote-item').forEach((item) => {
|
|
68
|
+
const refs = slideRoot!.querySelectorAll<HTMLElement>(
|
|
69
|
+
`.footnote-ref a[href="#${item.id}"]`,
|
|
70
|
+
)
|
|
71
|
+
let max = 0
|
|
72
|
+
refs.forEach((a) => {
|
|
73
|
+
const o = visibleOpacity(a, slideRoot!)
|
|
74
|
+
if (o > max)
|
|
75
|
+
max = o
|
|
76
|
+
})
|
|
77
|
+
// No reference found (e.g. print quirks) -> leave the footnote untouched.
|
|
78
|
+
const next = refs.length ? String(max) : ''
|
|
79
|
+
if (item.style.opacity !== next) {
|
|
80
|
+
item.style.opacity = next
|
|
81
|
+
changed = true
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
return changed
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// References fade over a CSS transition; follow it frame-by-frame until the
|
|
88
|
+
// value settles (a few stable frames) instead of snapping to the end state.
|
|
89
|
+
let rafId = 0
|
|
90
|
+
function syncAnimated() {
|
|
91
|
+
cancelAnimationFrame(rafId)
|
|
92
|
+
let stable = 0
|
|
93
|
+
const step = () => {
|
|
94
|
+
stable = syncOnce() ? 0 : stable + 1
|
|
95
|
+
if (stable < 4)
|
|
96
|
+
rafId = requestAnimationFrame(step)
|
|
97
|
+
}
|
|
98
|
+
step()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
onMounted(async () => {
|
|
102
|
+
slideRoot = anchorEl.value?.closest<HTMLElement>('[data-slidev-no]') ?? null
|
|
103
|
+
// A reference's fade is driven by CSS, so its transition events are our cue
|
|
104
|
+
// to re-follow the opacity even when no click index changed.
|
|
105
|
+
slideRoot?.addEventListener('transitionstart', syncAnimated)
|
|
106
|
+
slideRoot?.addEventListener('transitionend', syncAnimated)
|
|
107
|
+
await nextTick()
|
|
108
|
+
syncAnimated()
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
onBeforeUnmount(() => {
|
|
112
|
+
cancelAnimationFrame(rafId)
|
|
113
|
+
slideRoot?.removeEventListener('transitionstart', syncAnimated)
|
|
114
|
+
slideRoot?.removeEventListener('transitionend', syncAnimated)
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
// Re-sync when this slide becomes the active (teleporting) one, and on every
|
|
118
|
+
// click step that may reveal/hide a reference.
|
|
119
|
+
watch(isActive, () => nextTick(syncAnimated))
|
|
120
|
+
watch($clicks, () => nextTick(syncAnimated))
|
|
121
|
+
</script>
|
|
122
|
+
|
|
123
|
+
<template>
|
|
124
|
+
<!-- Stays in the slide body; only used to find the slide root above. -->
|
|
125
|
+
<span ref="anchorEl" class="hidden" />
|
|
126
|
+
<!-- `defer` (Vue 3.5+) resolves the target *after* the render flush, so when
|
|
127
|
+
currentPage flips the teleport finds global-bottom's freshly-rendered
|
|
128
|
+
target instead of racing it (which made the footnotes pop in late). -->
|
|
129
|
+
<Teleport v-if="isActive" :to="target" defer>
|
|
130
|
+
<div ref="listEl" class="contents">
|
|
131
|
+
<slot />
|
|
132
|
+
</div>
|
|
133
|
+
</Teleport>
|
|
134
|
+
</template>
|
|
135
|
+
|
|
136
|
+
<style>
|
|
137
|
+
/* Inline footnote reference ([^1] superscript) — stays in the slide body. */
|
|
138
|
+
.footnote-ref a {
|
|
139
|
+
@apply no-underline border-0 text-gray;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* The footnotes *block* is teleported into global-bottom.vue */
|
|
143
|
+
.footnotes {
|
|
144
|
+
@apply flex-auto flex flex-col justify-end pt-1 text-gray border-t-1 border-gray;
|
|
145
|
+
}
|
|
146
|
+
.footnotes p {
|
|
147
|
+
@apply m-0 text-xs;
|
|
148
|
+
}
|
|
149
|
+
.footnotes-list {
|
|
150
|
+
/* UnoCSS resets list-style off every ol/ul, which dropped the footnote
|
|
151
|
+
numbers; list-decimal re-enables them. pl-7 leaves room for the markers. */
|
|
152
|
+
@apply m-0 list-decimal pl-7;
|
|
153
|
+
}
|
|
154
|
+
.footnotes ::marker {
|
|
155
|
+
/* numbers a touch lighter than the note text so they read as labels */
|
|
156
|
+
@apply text-xs text-gray;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* markdown-it emits a separator rule and per-note backref links we don't want. */
|
|
160
|
+
.footnotes-sep,
|
|
161
|
+
.footnote-backref {
|
|
162
|
+
@apply hidden;
|
|
163
|
+
}
|
|
164
|
+
</style>
|
package/example.mdc
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
---
|
|
2
|
+
theme: ./
|
|
3
|
+
# Hash-based routing to make reload work on GitHub Pages
|
|
4
|
+
routerMode: hash
|
|
5
|
+
# layout: "cover"
|
|
6
|
+
author: "Your Name"
|
|
7
|
+
title: "Some very catchy title"
|
|
8
|
+
subtitle: "With a sub-title"
|
|
9
|
+
group: "Verified System Design Automation"
|
|
10
|
+
location: "Dresden"
|
|
11
|
+
|
|
12
|
+
# Use single quotes so YAML keeps the backslash literally (double quotes turn \t etc. into escapes).
|
|
13
|
+
date: '\today' # \today -> current date in the long format; \today[YYYY-MM-DD] for a custom day.js format
|
|
14
|
+
# date: '\now[YYYY-MM-DD HH:mm:ss]' # \now defaults to date + time; both \today and \now accept any day.js format
|
|
15
|
+
# date: "January 1st, 2000"
|
|
16
|
+
|
|
17
|
+
# footer: "{title}\n{group} / {author}\n{location}, {date}"
|
|
18
|
+
# footer: false
|
|
19
|
+
layout: "cover-white"
|
|
20
|
+
addons:
|
|
21
|
+
- slidev-component-progress
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<!-- If you want to have a different title on
|
|
25
|
+
the slide than in the metadata use a level 1 heading -->
|
|
26
|
+
|
|
27
|
+
# Here goes your fancy Title
|
|
28
|
+
|
|
29
|
+
<!-- same thing for the sub-title -->
|
|
30
|
+
## With another sub-title
|
|
31
|
+
|
|
32
|
+
<!--
|
|
33
|
+
The last comment on every page will be display
|
|
34
|
+
as the speaker notes in the presenter view
|
|
35
|
+
-->
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
layout: "cover-blue"
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
# A blue cover slide
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
layout: "section-white"
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
# A white section
|
|
48
|
+
|
|
49
|
+
## Using `section-white`
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
layout: "section"
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# And a blue section
|
|
57
|
+
|
|
58
|
+
## Using `section` or `section-blue`
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
layout: "section-n"
|
|
62
|
+
variant: 1
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# Here is the title of the section
|
|
67
|
+
|
|
68
|
+
Here is a subtitle, the name of the speaker, and additional
|
|
69
|
+
contextual information.
|
|
70
|
+
|
|
71
|
+
You can customize the colors within the TUD color set.
|
|
72
|
+
|
|
73
|
+
::detail::
|
|
74
|
+
|
|
75
|
+
This slide uses `section-n` with `variant: 1`.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
layout: "section-n"
|
|
79
|
+
variant: 2
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# Here is the title of the section
|
|
85
|
+
|
|
86
|
+
Here is a subtitle, the name of the speaker, and additional<br>
|
|
87
|
+
contextual information.
|
|
88
|
+
|
|
89
|
+
You can customize the colors within the TUD color set.
|
|
90
|
+
|
|
91
|
+
This slide uses `section-n` with `variant: 2`.
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
layout: "section-n"
|
|
96
|
+
variant: 3
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# Another section
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
Here is a subtitle, the name of the speaker, and additional<br>
|
|
104
|
+
contextual information.
|
|
105
|
+
|
|
106
|
+
You can customize the colors within the TUD color set.
|
|
107
|
+
|
|
108
|
+
::detail::
|
|
109
|
+
|
|
110
|
+
This slide uses `section-n` with `variant: 3`.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
layout: "section-n"
|
|
114
|
+
variant: 4
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# Another section
|
|
119
|
+
|
|
120
|
+
## Using `section-n` with `variant: 4`
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
layout: "section-n"
|
|
124
|
+
variant: 5
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# Another section
|
|
129
|
+
|
|
130
|
+
## Using `section-n` with `variant: 5`
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
layout: "section-n"
|
|
134
|
+
variant: 6
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# Another section
|
|
139
|
+
|
|
140
|
+
## Using `section-n` with `variant: 6`
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# A `default` slide
|
|
146
|
+
|
|
147
|
+
This slide shows the default layout
|
|
148
|
+
|
|
149
|
+
The TUD theme also supports _italic_, **bold** and `code` text,
|
|
150
|
+
as well as other markdown features like bullet lists:
|
|
151
|
+
|
|
152
|
+
- statement 1
|
|
153
|
+
- statement 2
|
|
154
|
+
|
|
155
|
+
## 2nd level heading
|
|
156
|
+
|
|
157
|
+
normal lists:
|
|
158
|
+
|
|
159
|
+
1. test
|
|
160
|
+
2. test
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
# Other markdown features
|
|
165
|
+
|
|
166
|
+
::div{.flex.justify-between}
|
|
167
|
+
## Blockquotes:
|
|
168
|
+
|
|
169
|
+
> This is a very important
|
|
170
|
+
> quote from a very important person
|
|
171
|
+
::
|
|
172
|
+
|
|
173
|
+
> # Theorem 1 {.test}
|
|
174
|
+
> Bla bla bla bla blaa
|
|
175
|
+
> theorem bla bla bla
|
|
176
|
+
>
|
|
177
|
+
> $$f(x) := y \times z^2$$
|
|
178
|
+
|
|
179
|
+
::div{.flex.justify-between.items-center}
|
|
180
|
+
::div
|
|
181
|
+
| Left Align | Center Align | Right Align |
|
|
182
|
+
|:-----------|:------------:|------------:|
|
|
183
|
+
| 1 | 1 | 1 |
|
|
184
|
+
| 2 | 2 | 2 |
|
|
185
|
+
| 3 | 3 | 3 |
|
|
186
|
+
|
|
187
|
+
A plain caption underneath the table. {.caption}
|
|
188
|
+
::
|
|
189
|
+
|
|
190
|
+
## Tables
|
|
191
|
+
|
|
192
|
+
::div
|
|
193
|
+
| Left Align | Center Align | Right Align |
|
|
194
|
+
|:-----------|:------------:|------------:|
|
|
195
|
+
| 1 | 1 | 1 |
|
|
196
|
+
| 2 | 2 | 2 |
|
|
197
|
+
| 3 | 3 | 3 |
|
|
198
|
+
|
|
199
|
+
A numbered caption with a "Table N:" prefix. {.caption .numbered}
|
|
200
|
+
::
|
|
201
|
+
::
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
# More numbered tables
|
|
206
|
+
|
|
207
|
+
::div{.flex.justify-between.items-center}
|
|
208
|
+
::div
|
|
209
|
+
| Left Align | Center Align | Right Align |
|
|
210
|
+
|:-----------|:------------:|------------:|
|
|
211
|
+
| 1 | 1 | 1 |
|
|
212
|
+
| 2 | 2 | 2 |
|
|
213
|
+
| 3 | 3 | 3 |
|
|
214
|
+
|
|
215
|
+
A plain caption underneath the table. {.caption .numbered}
|
|
216
|
+
::
|
|
217
|
+
|
|
218
|
+
## Tables
|
|
219
|
+
|
|
220
|
+
::div
|
|
221
|
+
| Left Align | Center Align | Right Align |
|
|
222
|
+
|:-----------|:------------:|------------:|
|
|
223
|
+
| 1 | 1 | 1 |
|
|
224
|
+
| 2 | 2 | 2 |
|
|
225
|
+
| 3 | 3 | 3 |
|
|
226
|
+
|
|
227
|
+
A numbered caption with a "Table N:" prefix. {.caption .numbered}
|
|
228
|
+
::
|
|
229
|
+
::
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
# Latex support
|
|
234
|
+
|
|
235
|
+
Did you ever use google slides for a theoretical presentation?
|
|
236
|
+
Well then you probably had a lot of pain with formulas.
|
|
237
|
+
|
|
238
|
+
But with the right tools formulas can be as easy as writing a bit of latex.
|
|
239
|
+
|
|
240
|
+
$$
|
|
241
|
+
\forall\, \green{p}~src.\\
|
|
242
|
+
\texttt{\red{in}}[src] = \green{p} \to \lozenge~\texttt{\blue{out}}[p.dst] = \green{p}
|
|
243
|
+
$$
|
|
244
|
+
|
|
245
|
+
Note the usage of the official color scheme inside of latex formulas
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
layout: "cols"
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
# A slots layout with multiple columns
|
|
252
|
+
|
|
253
|
+
This layout is named `cols`
|
|
254
|
+
|
|
255
|
+
> You can put some content above the columns that will span then whole slide
|
|
256
|
+
|
|
257
|
+
::col-1::
|
|
258
|
+
|
|
259
|
+
## First {.red}
|
|
260
|
+
|
|
261
|
+
This shows on the left in red
|
|
262
|
+
|
|
263
|
+
::col-3::
|
|
264
|
+
|
|
265
|
+
## Third {.green}
|
|
266
|
+
|
|
267
|
+
This shows on the right in green
|
|
268
|
+
|
|
269
|
+
::col-2::
|
|
270
|
+
|
|
271
|
+
## Second {.magenta}
|
|
272
|
+
|
|
273
|
+
This shows in the middle in magenta
|
|
274
|
+
|
|
275
|
+
::bottom::
|
|
276
|
+
|
|
277
|
+
::div{.violet}
|
|
278
|
+
> # The `bottom` slot
|
|
279
|
+
>
|
|
280
|
+
> This is shown on the bottom (below the columns) and spans the whole slide again.
|
|
281
|
+
::
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
# Code examples
|
|
286
|
+
|
|
287
|
+
Enjoy the ligatures of FiraCode: (And automatic syntax highlighting)
|
|
288
|
+
|
|
289
|
+
```coq /stalls/ [some-title.js ~~]
|
|
290
|
+
Lemma reset_all_inputs_nsp_correct {data_t dims IdxEnv} {lcl : idx_t dims} (nsp : @noc_state_partial data_t dims IdxEnv) ext1 ext2
|
|
291
|
+
(stalls : vect bool (length dims * 2 * 2)) :
|
|
292
|
+
(∀ i,
|
|
293
|
+
vect_nth stalls i = false ->
|
|
294
|
+
vect_nth nsp.(nsp_pkgs1)?[vect_nth (list_neighbors_du lcl) (idx_div 2 i)] i = None) ->
|
|
295
|
+
∀ sig REnv (sigma : ∀ f : ext_fn_t dims, Sig_denote (Sigma (data_t:=data_t) dims f)) Γv Q,
|
|
296
|
+
kpm_entails_ret (R:=R dims) (REnv:=REnv) (represent_nsp (nsp_map_pkgs1 nsp (in_channel_update lcl (reset_all_inputs_spec stalls))) ext1 ext2) Γv (tau:=unit_t) (eq Ob) Q ->
|
|
297
|
+
kpm_entails (R:=R dims) (REnv:=REnv) (represent_nsp nsp ext1 ext2) Γv (wp_total (sigma:=sigma) (sig:=sig) (InternalCall (reset_all_inputs lcl) (ConstCtx #{
|
|
298
|
+
("stalls", array_t (bits_t 1) (length dims * 2 * 2)) => represent stalls
|
|
299
|
+
}#)) Q).
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
```js
|
|
303
|
+
function recolor(theme: any, shade: 1 | 2) {
|
|
304
|
+
return {
|
|
305
|
+
...theme,
|
|
306
|
+
tokenColors: theme.tokenColors?.map((rule: any) => {
|
|
307
|
+
const scopes: string[] = (Array.isArray(rule.scope) ? rule.scope : [rule.scope]).filter(Boolean)
|
|
308
|
+
if (scopes.some(isComment)) return rule
|
|
309
|
+
const category = CATEGORIES.find(c => scopes.some(c.match))
|
|
310
|
+
if (!category || !rule.settings?.foreground) return rule
|
|
311
|
+
return { ...rule, settings: { ...rule.settings, foreground: category.color(shade) } }
|
|
312
|
+
}),
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
# Images with captions
|
|
320
|
+
|
|
321
|
+
Add `{.caption}` to an image and its alt text becomes a LaTeX-style
|
|
322
|
+
caption below it:
|
|
323
|
+
|
|
324
|
+
{.caption .w-40}
|
|
325
|
+
|
|
326
|
+
::div{.flex.justify-between}
|
|
327
|
+
::div{.flex.flex-col.items-center}
|
|
328
|
+
Add `{.numbered}` as well for a "Figure N:" prefix:
|
|
329
|
+
|
|
330
|
+
{.caption .numbered .w-60}
|
|
331
|
+
::
|
|
332
|
+
::div{.flex.flex-col.items-center}
|
|
333
|
+
Without the class, an image renders as usual (no caption):
|
|
334
|
+
|
|
335
|
+
{.w-60}
|
|
336
|
+
::
|
|
337
|
+
::
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
<!-- # Footnotes -->
|
|
342
|
+
|
|
343
|
+
<v-click>
|
|
344
|
+
|
|
345
|
+
And another footnote here[^note2][]
|
|
346
|
+
|
|
347
|
+
</v-click>
|
|
348
|
+
|
|
349
|
+
[^note2]: another 2nd footnote
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
Test[^note][]
|
|
353
|
+
|
|
354
|
+
[^note]: Some test
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
# More Footnotes
|
|
359
|
+
|
|
360
|
+
<v-click>
|
|
361
|
+
|
|
362
|
+
And another footnote here[^note2][]
|
|
363
|
+
|
|
364
|
+
</v-click>
|
|
365
|
+
|
|
366
|
+
[^note2]: different footnote
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
Test[^note][] [^note3][]
|
|
370
|
+
|
|
371
|
+
[^note]: another one
|
|
372
|
+
[^note3]: another one
|
package/flake.lock
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nodes": {
|
|
3
|
+
"flake-utils": {
|
|
4
|
+
"inputs": {
|
|
5
|
+
"systems": "systems"
|
|
6
|
+
},
|
|
7
|
+
"locked": {
|
|
8
|
+
"lastModified": 1731533236,
|
|
9
|
+
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
|
10
|
+
"owner": "numtide",
|
|
11
|
+
"repo": "flake-utils",
|
|
12
|
+
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
|
13
|
+
"type": "github"
|
|
14
|
+
},
|
|
15
|
+
"original": {
|
|
16
|
+
"owner": "numtide",
|
|
17
|
+
"repo": "flake-utils",
|
|
18
|
+
"type": "github"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"nixpkgs": {
|
|
22
|
+
"locked": {
|
|
23
|
+
"lastModified": 1768649915,
|
|
24
|
+
"narHash": "sha256-jc21hKogFnxU7KXSVTRmxC7u5D4RHwm9BAvDf5/Z1Uo=",
|
|
25
|
+
"owner": "nixos",
|
|
26
|
+
"repo": "nixpkgs",
|
|
27
|
+
"rev": "3e3f3c7f9977dc123c23ee21e8085ed63daf8c37",
|
|
28
|
+
"type": "github"
|
|
29
|
+
},
|
|
30
|
+
"original": {
|
|
31
|
+
"owner": "nixos",
|
|
32
|
+
"ref": "release-25.05",
|
|
33
|
+
"repo": "nixpkgs",
|
|
34
|
+
"type": "github"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"root": {
|
|
38
|
+
"inputs": {
|
|
39
|
+
"flake-utils": "flake-utils",
|
|
40
|
+
"nixpkgs": "nixpkgs"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"systems": {
|
|
44
|
+
"locked": {
|
|
45
|
+
"lastModified": 1681028828,
|
|
46
|
+
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
47
|
+
"owner": "nix-systems",
|
|
48
|
+
"repo": "default",
|
|
49
|
+
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
50
|
+
"type": "github"
|
|
51
|
+
},
|
|
52
|
+
"original": {
|
|
53
|
+
"owner": "nix-systems",
|
|
54
|
+
"repo": "default",
|
|
55
|
+
"type": "github"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"root": "root",
|
|
60
|
+
"version": 7
|
|
61
|
+
}
|
package/flake.nix
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
inputs = {
|
|
3
|
+
nixpkgs.url = "github:nixos/nixpkgs/release-25.05";
|
|
4
|
+
flake-utils.url = "github:numtide/flake-utils";
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
outputs = { self, nixpkgs, flake-utils }:
|
|
8
|
+
flake-utils.lib.eachDefaultSystem (system:
|
|
9
|
+
let
|
|
10
|
+
pkgs = import nixpkgs {
|
|
11
|
+
inherit system;
|
|
12
|
+
overlays = [ ];
|
|
13
|
+
};
|
|
14
|
+
in
|
|
15
|
+
{
|
|
16
|
+
# devShells.default = self.packages.${system}.default;
|
|
17
|
+
devShells.default = pkgs.mkShell {
|
|
18
|
+
packages = [ pkgs.pnpm pkgs.nodejs ];
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<Background
|
|
4
|
+
:bl="pageLogo?.bl" :tr="pageLogo?.tr" :fill="pageLogo?.fill"
|
|
5
|
+
:background="pageBackground"
|
|
6
|
+
/>
|
|
7
|
+
|
|
8
|
+
<div v-html="rawLogoText"
|
|
9
|
+
:style="{ fill: logos.text }" :class="{'opacity-0': !logos.text}"
|
|
10
|
+
class="[&>svg]:w-[220px] duration-[0.5s] transition-[opacity,fill] absolute left-[64px] top-[42px] z-10"
|
|
11
|
+
></div>
|
|
12
|
+
<div v-html="rawLogo"
|
|
13
|
+
:style="{ fill: logos.normal }" :class="{'opacity-0': !logos.normal}"
|
|
14
|
+
class="[&>svg]:w-[68px] duration-[0.5s] transition-[opacity,fill] absolute left-[64px] top-[42px] z-10"
|
|
15
|
+
></div>
|
|
16
|
+
|
|
17
|
+
<div v-html="rawLogoSmall"
|
|
18
|
+
:style="{ fill: logos.small }" :class="{'opacity-0': !logos.small}"
|
|
19
|
+
class="duration-[0.5s] transition-[opacity,fill] absolute left-[64px] top-[660px] z-10 w-[54px]"
|
|
20
|
+
></div>
|
|
21
|
+
|
|
22
|
+
<footer class="absolute bottom-0 h-16 pb-[13px] pr-[64px] pl-[164px] flex items-baseline gap-x-6 w-full z-100">
|
|
23
|
+
<div :class="{'opacity-0': !show_footer}" class="duration-[0.5s] transition-opacity text-primary">
|
|
24
|
+
<div v-if="$slidev.configs.footer !== false" class="whitespace-pre">
|
|
25
|
+
{{ footer }}
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<!-- Footnotes teleport target (see components/Footnotes.vue) -->
|
|
30
|
+
<div class="relative flex-1 min-w-0 self-end flex flex-col h-full">
|
|
31
|
+
<div :id="footnotesTargetId" class="absolute bottom-0 w-full min-h-full pb-2"></div>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div :class="{'opacity-0': !show_footer}" class="duration-[0.5s] transition-opacity w-[66px]">
|
|
35
|
+
<div class="flex items-baseline justify-center">
|
|
36
|
+
<span class="flex-1 text-right font-bold text-lg text-primary">{{ $nav.currentPage }}</span>
|
|
37
|
+
<span :class="{ 'opacity-0': $nav.clicksTotal == 0 }" class="text-left text-gray text-xs">.</span>
|
|
38
|
+
<span :class="{ 'opacity-0': $nav.clicksTotal == 0 }" class="flex-1 text-left text-gray text-xs">{{ $nav.clicks+1 }}</span>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</footer>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
44
|
+
<script setup lang="ts">
|
|
45
|
+
import { useSlideContext } from '@slidev/client'
|
|
46
|
+
import { computed, unref } from 'vue';
|
|
47
|
+
import { expandDateTokens } from './scripts/util';
|
|
48
|
+
import { formatString } from './scripts/util';
|
|
49
|
+
import { slideBackgrounds, slideBgLogos, slideLogos } from './scripts/background';
|
|
50
|
+
|
|
51
|
+
import rawLogo from './assets/TUD-logo-no-color.svg?raw';
|
|
52
|
+
import rawLogoSmall from './assets/TUD-logo-text-small-no-color.svg?raw';
|
|
53
|
+
import rawLogoText from './assets/TUD-logo-text-no-color.svg?raw';
|
|
54
|
+
|
|
55
|
+
const { $slidev, $nav } = useSlideContext()
|
|
56
|
+
const pageBackground = computed(() => slideBackgrounds[$nav.value.currentPage] ?? 'transparent')
|
|
57
|
+
|
|
58
|
+
// use $nav instead of useNav to ensure that the export works correctly
|
|
59
|
+
const footnotesTargetId = computed(() => `footnotes-containter-${unref(($nav as any).value.currentPage)}`)
|
|
60
|
+
|
|
61
|
+
const logos = computed(() => slideLogos[$nav.value.currentPage] ?? {})
|
|
62
|
+
|
|
63
|
+
const show_footer = computed(() => !new Set(['cover', 'cover-blue', 'cover-white', 'section', 'section-blue', 'section-white', 'section-n']).has($nav.value.currentLayout))
|
|
64
|
+
|
|
65
|
+
const get_date = computed(() => {
|
|
66
|
+
const d = ($slidev.configs as any).date
|
|
67
|
+
return d ? expandDateTokens(String(d)) : d
|
|
68
|
+
})
|
|
69
|
+
const footer = computed(() => {
|
|
70
|
+
let fstring = "{title} • {author}"
|
|
71
|
+
return formatString(($slidev.configs as any).footer ?
|
|
72
|
+
($slidev.configs as any).footer : fstring,
|
|
73
|
+
{...$slidev.configs, date: get_date.value}
|
|
74
|
+
)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
const pageLogo = computed(() => slideBgLogos[$nav.value.currentPage])
|
|
78
|
+
|
|
79
|
+
</script>
|