slidev-theme-tud-db 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/README.md +61 -0
- package/assets/ddrg-color.svg +1 -0
- package/assets/ddrg-white.svg +1 -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/assets/mosaic.svg +1 -0
- package/assets/section-mosaic.svg +1 -0
- package/assets/tud-black.svg +1 -0
- package/assets/tud-white.svg +1 -0
- package/components/DbFrame.vue +24 -0
- package/global-bottom.vue +31 -0
- package/layouts/cover.vue +49 -0
- package/layouts/default.vue +13 -0
- package/layouts/section-num.vue +81 -0
- package/layouts/section.vue +37 -0
- package/layouts/two-cols-grid.vue +41 -0
- package/layouts/two-cols-header.vue +28 -0
- package/markdown.ts +197 -0
- package/package.json +71 -0
- package/setup/shiki.ts +13 -0
- package/styles/db-theme.css +337 -0
- package/styles/fade-transition.css +36 -0
- package/styles/font.css +28 -0
- package/styles/index.ts +6 -0
- package/vite.config.ts +70 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/* Dresden Database Research Group — local Slidev theme
|
|
2
|
+
* Step 1: white slide base + Noto Sans + DB color tokens.
|
|
3
|
+
* Colors extracted from DB_template.potx (theme1.xml). */
|
|
4
|
+
|
|
5
|
+
:root {
|
|
6
|
+
--db-navy: #001450;
|
|
7
|
+
--db-text: #4c4d4d;
|
|
8
|
+
--db-text-soft: #171616;
|
|
9
|
+
--db-gray-light: #e7e6e6;
|
|
10
|
+
|
|
11
|
+
--db-accent1: #40b498; /* teal-green */
|
|
12
|
+
--db-accent2: #b1d285; /* light green */
|
|
13
|
+
--db-accent3: #1f8299; /* blue-teal (links) */
|
|
14
|
+
--db-accent4: #f9c611; /* yellow */
|
|
15
|
+
--db-accent5: #ea4f30; /* red-orange */
|
|
16
|
+
--db-accent6: #994781; /* purple */
|
|
17
|
+
|
|
18
|
+
--db-heading-blue: #2f57b2; /* content sub-headers */
|
|
19
|
+
--db-footer-bg: #e7e9ed; /* bottom footer band */
|
|
20
|
+
--db-table-stripe: #dbdbdb; /* zebra-striped table rows */
|
|
21
|
+
--db-table-rule: #b9b9b9; /* table header/footer rule lines */
|
|
22
|
+
|
|
23
|
+
/* Slidev theme variables */
|
|
24
|
+
--slidev-theme-primary: var(--db-accent3);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Base: plain white slide, near-black body text.
|
|
28
|
+
* (--db-text grey is reserved for muted bits: table footer, page number.)
|
|
29
|
+
* height:100% fills the slide (theme provides this; not inherited from
|
|
30
|
+
* @slidev/theme-default anymore). */
|
|
31
|
+
.slidev-layout {
|
|
32
|
+
height: 100%;
|
|
33
|
+
background: #ffffff;
|
|
34
|
+
color: var(--db-text-soft);
|
|
35
|
+
font-family: 'NotoSans', ui-sans-serif, system-ui, sans-serif;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.slidev-layout h1,
|
|
39
|
+
.slidev-layout h2,
|
|
40
|
+
.slidev-layout h3 {
|
|
41
|
+
color: var(--db-navy);
|
|
42
|
+
font-weight: 700;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Inline code "pills": slimmer so they don't bloat line height in bullets.
|
|
46
|
+
(Slidev default is ~2px 6px / 0.9em.) Fenced code (pre > code) is untouched. */
|
|
47
|
+
.slidev-layout.db-default :not(pre) > code {
|
|
48
|
+
padding: 1px 0; /* no horizontal padding by default so it sits flush with text */
|
|
49
|
+
font-size: 0.85em;
|
|
50
|
+
line-height: 1;
|
|
51
|
+
background: transparent !important; /* transparent by default */
|
|
52
|
+
}
|
|
53
|
+
/* Opt-in faint background for inline code */
|
|
54
|
+
.slidev-layout.db-default :not(pre) > code.with-bg {
|
|
55
|
+
padding: 1px 4px; /* add horizontal padding back for the background box */
|
|
56
|
+
background: rgba(0, 0, 0, 0.03) !important;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.slidev-layout a {
|
|
60
|
+
color: var(--db-accent3);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* Content slides ("Titel und Inhalt").
|
|
64
|
+
* Canvas is 720px wide (== 720pt real slide), so px values below equal PowerPoint pt. */
|
|
65
|
+
.slidev-layout.db-default {
|
|
66
|
+
font-size: 13px; /* bullet / body text = 13pt */
|
|
67
|
+
line-height: 1.15; /* tight line spacing */
|
|
68
|
+
padding: 0; /* we control spacing via the body wrapper + footer */
|
|
69
|
+
}
|
|
70
|
+
.slidev-layout.db-default h1 {
|
|
71
|
+
color: var(--db-text-soft); /* black/gray page heading */
|
|
72
|
+
font-size: 22px; /* 22pt */
|
|
73
|
+
line-height: 1.2;
|
|
74
|
+
margin-bottom: 36px; /* gap to first sub-header (~36pt in template) */
|
|
75
|
+
}
|
|
76
|
+
.slidev-layout.db-default h2,
|
|
77
|
+
.slidev-layout.db-default h3 {
|
|
78
|
+
color: var(--db-heading-blue); /* blue sub-headers */
|
|
79
|
+
font-size: 15px; /* 15pt */
|
|
80
|
+
line-height: 1.25;
|
|
81
|
+
margin-top: 24px; /* space ABOVE a sub-header, whatever precedes it
|
|
82
|
+
(bullet list, code block, paragraph, …) */
|
|
83
|
+
}
|
|
84
|
+
/* …except a sub-header that is the FIRST content of its area (right under the
|
|
85
|
+
page title, or the top of a column / grid cell) — the title's margin-bottom
|
|
86
|
+
or the grid gap already provides that separation.
|
|
87
|
+
This is wrap-proof: a section wrapped in a <div> (e.g. a GSAP animation
|
|
88
|
+
anchor) is still treated as "top" when its wrapper is the first child, but a
|
|
89
|
+
wrapped section that FOLLOWS other content keeps the 24px gap. So adding a
|
|
90
|
+
wrapper div later does NOT collapse the spacing. (default layout: h1 is a
|
|
91
|
+
sibling of the content; two-cols-header: .db-grid__col; two-cols-grid:
|
|
92
|
+
.db-rowgrid cells.) */
|
|
93
|
+
.slidev-layout.db-default :is(h1 + h2, h1 + h3),
|
|
94
|
+
.slidev-layout.db-default h1 + div > :is(h2, h3):first-child,
|
|
95
|
+
.slidev-layout.db-default .db-grid__col > :is(h2, h3):first-child,
|
|
96
|
+
.slidev-layout.db-default .db-grid__col > div:first-child > :is(h2, h3):first-child,
|
|
97
|
+
.slidev-layout.db-default .db-rowgrid > div > :is(h2, h3):first-child,
|
|
98
|
+
.slidev-layout.db-default .db-rowgrid > div > div:first-child > :is(h2, h3):first-child {
|
|
99
|
+
margin-top: 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* Lists (ul + ol share indentation/spacing): ul level1 = disc, level2 = square;
|
|
103
|
+
* ol = numbers. margin-left indents markers from the heading; padding-left is
|
|
104
|
+
* the marker→text gap. */
|
|
105
|
+
.slidev-layout.db-default ul,
|
|
106
|
+
.slidev-layout.db-default ol {
|
|
107
|
+
margin-left: 0.6em; /* first-level bullet indentation (nested lists track this) */
|
|
108
|
+
padding-left: 1.1em;
|
|
109
|
+
}
|
|
110
|
+
.slidev-layout.db-default ul { list-style-type: disc; }
|
|
111
|
+
.slidev-layout.db-default ol { list-style-type: decimal; }
|
|
112
|
+
.slidev-layout.db-default ul ul,
|
|
113
|
+
.slidev-layout.db-default ol ol {
|
|
114
|
+
margin-left: 0; /* 2nd-level marker aligns with 1st-level text (no extra indent) */
|
|
115
|
+
font-size: 12px; /* 2nd-level text a touch smaller (12pt vs 13pt) */
|
|
116
|
+
}
|
|
117
|
+
.slidev-layout.db-default ul ul { list-style-type: square; }
|
|
118
|
+
/* Tight vertical rhythm (theme defaults to ~1.8 line-height) */
|
|
119
|
+
.slidev-layout.db-default li,
|
|
120
|
+
.slidev-layout.db-default p {
|
|
121
|
+
line-height: 1.25;
|
|
122
|
+
}
|
|
123
|
+
.slidev-layout.db-default li {
|
|
124
|
+
margin: 0.15em 0; /* slight spacing between bullets */
|
|
125
|
+
}
|
|
126
|
+
.slidev-layout.db-default p {
|
|
127
|
+
margin: 0.5em 0; /* tight spacing between paragraphs */
|
|
128
|
+
}
|
|
129
|
+
/* Inside list items Markdown wraps text in <p> when the item also contains a
|
|
130
|
+
block (e.g. a code block) -> a "loose" list. Zero those margins so such a
|
|
131
|
+
bullet is as tight as a plain one. */
|
|
132
|
+
.slidev-layout.db-default li p {
|
|
133
|
+
margin: 0;
|
|
134
|
+
}
|
|
135
|
+
.slidev-layout.db-default li::marker {
|
|
136
|
+
color: var(--db-text-soft);
|
|
137
|
+
}
|
|
138
|
+
/* Shrink only the bullet glyphs (• ▪); ordered-list numbers keep text size. */
|
|
139
|
+
.slidev-layout.db-default ul li::marker {
|
|
140
|
+
font-size: 0.8em;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* Blockquotes -> a muted italic aside with a leading en-dash
|
|
144
|
+
(the "– …" secondary-note style). */
|
|
145
|
+
.slidev-layout.db-default blockquote {
|
|
146
|
+
margin: 0.4em 0;
|
|
147
|
+
padding: 0;
|
|
148
|
+
border: none;
|
|
149
|
+
background: transparent;
|
|
150
|
+
font-style: italic;
|
|
151
|
+
color: var(--db-text); /* muted grey */
|
|
152
|
+
}
|
|
153
|
+
.slidev-layout.db-default blockquote p {
|
|
154
|
+
margin: 0;
|
|
155
|
+
}
|
|
156
|
+
.slidev-layout.db-default blockquote > p:first-child::before {
|
|
157
|
+
content: '– ';
|
|
158
|
+
}
|
|
159
|
+
.slidev-layout.db-default blockquote code {
|
|
160
|
+
font-style: normal; /* keep inline code upright inside the italic aside */
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* Fenced code blocks: box only as wide as its content, not full slide width.
|
|
164
|
+
fit-content on the WRAPPER so an optional caption + the code share one width.
|
|
165
|
+
max-width keeps long lines from overflowing the slide. */
|
|
166
|
+
.slidev-layout.db-default .slidev-code-wrapper {
|
|
167
|
+
width: fit-content;
|
|
168
|
+
max-width: 100%;
|
|
169
|
+
}
|
|
170
|
+
/* Default to transparent background for multi-line blocks, overriding Shiki */
|
|
171
|
+
.slidev-layout.db-default pre.slidev-code {
|
|
172
|
+
background: transparent !important;
|
|
173
|
+
}
|
|
174
|
+
/* Opt-in faint background via ```lang {class:'with-bg'} */
|
|
175
|
+
.slidev-layout.db-default .with-bg pre.slidev-code {
|
|
176
|
+
background: rgba(0, 0, 0, 0.03) !important;
|
|
177
|
+
}
|
|
178
|
+
/* Code sizing (Slidev defaults: 12px / 18px / 8px). Slightly smaller font and
|
|
179
|
+
tighter vertical padding so the box hugs the code top and bottom. */
|
|
180
|
+
.slidev-layout.db-default {
|
|
181
|
+
--slidev-code-font-size: 11px;
|
|
182
|
+
--slidev-code-line-height: 1.3;
|
|
183
|
+
--slidev-code-padding: 4px 10px;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* Line numbers (```lang {lines:true}```): tighten the gutter. Slidev's defaults
|
|
187
|
+
are a wide 24px gap between the number and the code, plus the block's 10px
|
|
188
|
+
left padding before the number. Both are scoped to line-numbered blocks so
|
|
189
|
+
plain code blocks keep their normal padding. */
|
|
190
|
+
.slidev-layout.db-default .slidev-code-line-numbers .slidev-code {
|
|
191
|
+
/* override the padding *variable* (Slidev applies padding via it, which beats
|
|
192
|
+
a plain padding-left here). top right bottom left — only the left shrinks. */
|
|
193
|
+
--slidev-code-padding: 4px 10px 4px 6px; /* less space left of the numbers (was 10px) */
|
|
194
|
+
}
|
|
195
|
+
.slidev-layout.db-default .slidev-code-line-numbers .slidev-code code .line::before {
|
|
196
|
+
width: 1ch; /* was 16px — the wide right-aligned column left a big empty
|
|
197
|
+
gap to the LEFT of single-digit numbers */
|
|
198
|
+
/* separator between numbers and code: each line's ::before carries a right
|
|
199
|
+
border; stacked, they read as one continuous vertical rule. */
|
|
200
|
+
padding-right: 10px; /* number → separator */
|
|
201
|
+
border-right: 1px solid var(--db-table-rule);
|
|
202
|
+
margin-right: 7px; /* separator → code (was a plain 8px gap) */
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/* Optional caption above a code block.
|
|
206
|
+
Authoring: ```python [What this snippet does] */
|
|
207
|
+
.slidev-layout.db-default .slidev-code-block-title {
|
|
208
|
+
padding: 3px 10px;
|
|
209
|
+
background: transparent; /* drop Slidev's heavy gray title bar */
|
|
210
|
+
font-size: 11px;
|
|
211
|
+
font-style: italic;
|
|
212
|
+
color: var(--db-text);
|
|
213
|
+
opacity: 0.85;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* Optional table captions (need Comark, enabled by this theme).
|
|
217
|
+
ABOVE the table: [Title]{.table-caption} -> black, non-italic
|
|
218
|
+
BELOW the table: [Note]{.table-footer} -> small italic, muted */
|
|
219
|
+
.slidev-layout.db-default p:has(.table-caption),
|
|
220
|
+
.slidev-layout.db-default p:has(.table-footer) {
|
|
221
|
+
display: block;
|
|
222
|
+
}
|
|
223
|
+
.slidev-layout.db-default .table-caption,
|
|
224
|
+
.slidev-layout.db-default p:has(.table-caption),
|
|
225
|
+
.slidev-layout.db-default .table-footer,
|
|
226
|
+
.slidev-layout.db-default p:has(.table-footer) {
|
|
227
|
+
font-size: 11px;
|
|
228
|
+
background: transparent !important;
|
|
229
|
+
}
|
|
230
|
+
.slidev-layout.db-default .table-caption,
|
|
231
|
+
.slidev-layout.db-default .table-footer {
|
|
232
|
+
display: inline !important; /* override UnoCSS table-caption utility */
|
|
233
|
+
}
|
|
234
|
+
.slidev-layout.db-default .table-caption,
|
|
235
|
+
.slidev-layout.db-default p:has(.table-caption) {
|
|
236
|
+
color: var(--db-text-soft); /* black, non-italic title above */
|
|
237
|
+
}
|
|
238
|
+
.slidev-layout.db-default .table-footer,
|
|
239
|
+
.slidev-layout.db-default p:has(.table-footer) {
|
|
240
|
+
font-style: italic; /* muted note below */
|
|
241
|
+
color: var(--db-text);
|
|
242
|
+
opacity: 0.85;
|
|
243
|
+
}
|
|
244
|
+
.slidev-layout.db-default .caption-label {
|
|
245
|
+
font-weight: bold;
|
|
246
|
+
font-style: normal;
|
|
247
|
+
}
|
|
248
|
+
/* sit tight against the table */
|
|
249
|
+
.slidev-layout.db-default p:has(.table-caption) {
|
|
250
|
+
margin: 0 0 2px;
|
|
251
|
+
}
|
|
252
|
+
.slidev-layout.db-default p:has(.table-caption) + table {
|
|
253
|
+
margin-top: 0;
|
|
254
|
+
}
|
|
255
|
+
.slidev-layout.db-default table:has(+ p .table-footer) {
|
|
256
|
+
margin-bottom: 2px;
|
|
257
|
+
}
|
|
258
|
+
.slidev-layout.db-default p:has(.table-footer) {
|
|
259
|
+
margin: 0;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* Tables: borderless with zebra striping + header/footer rules (template look).
|
|
263
|
+
Column alignment (e.g. centering `id`) is set per-table in markdown (:---:). */
|
|
264
|
+
.slidev-layout.db-default table {
|
|
265
|
+
border-collapse: collapse;
|
|
266
|
+
width: auto; /* default: hug content */
|
|
267
|
+
font-size: 10px; /* 10pt (canvas 720 => px == pt) */
|
|
268
|
+
}
|
|
269
|
+
/* Width control: tables hug content by default. To pin a width, wrap in
|
|
270
|
+
<div class="table-w" style="width: …"> — the table then fills that box, so
|
|
271
|
+
giving two tables the same width makes them equal size.
|
|
272
|
+
<div class="table-w" style="width: 360px"> -> fixed 360px
|
|
273
|
+
<div class="table-w w-2/3"> -> two-thirds of the column
|
|
274
|
+
<div class="table-w"> -> full column/slide width */
|
|
275
|
+
.slidev-layout.db-default .table-w table {
|
|
276
|
+
width: 100%;
|
|
277
|
+
}
|
|
278
|
+
/* Equal-width group: wrap several tables in <div class="table-equal"> and they
|
|
279
|
+
all take the width of the widest one (shared max-content grid column). */
|
|
280
|
+
.slidev-layout.db-default .table-equal {
|
|
281
|
+
display: grid;
|
|
282
|
+
grid-template-columns: max-content;
|
|
283
|
+
}
|
|
284
|
+
.slidev-layout.db-default .table-equal table {
|
|
285
|
+
width: 100%;
|
|
286
|
+
}
|
|
287
|
+
/* Reach: let a table in one column spill into the neighbour by a set amount.
|
|
288
|
+
Wrap it and set --reach to how far it should extend left (toward the other
|
|
289
|
+
column), giving its columns that much more room.
|
|
290
|
+
<div class="table-reach" style="--reach: 120px"> … table … </div>
|
|
291
|
+
Note: it overlaps whatever sits in the neighbour column at that height, so
|
|
292
|
+
pick a --reach that clears it (best where that area is empty). */
|
|
293
|
+
.slidev-layout.db-default .table-reach {
|
|
294
|
+
--reach: 0px;
|
|
295
|
+
width: calc(100% + var(--reach));
|
|
296
|
+
margin-left: calc(-1 * var(--reach));
|
|
297
|
+
}
|
|
298
|
+
.slidev-layout.db-default .table-reach table {
|
|
299
|
+
width: 100%;
|
|
300
|
+
}
|
|
301
|
+
.slidev-layout.db-default th,
|
|
302
|
+
.slidev-layout.db-default td {
|
|
303
|
+
border: none; /* no vertical/cell borders */
|
|
304
|
+
padding: 2px 8px 4px; /* tight padding; bottom>top optically centers
|
|
305
|
+
single-line text (nudges it up) */
|
|
306
|
+
vertical-align: middle; /* center cell text vertically */
|
|
307
|
+
text-align: center; /* center by default; :--/--: in markdown override */
|
|
308
|
+
}
|
|
309
|
+
/* Space between stacked tables — top margin on every table after the first.
|
|
310
|
+
(Equivalent to bottom-margin-on-all-but-last; NOT the same as bottom-margin
|
|
311
|
+
on all, which would also add a gap after the last table.) */
|
|
312
|
+
.slidev-layout.db-default table:not(:first-of-type) {
|
|
313
|
+
margin-top: 14px;
|
|
314
|
+
}
|
|
315
|
+
.slidev-layout.db-default thead th {
|
|
316
|
+
font-weight: 700;
|
|
317
|
+
color: var(--db-text-soft);
|
|
318
|
+
background: #fff;
|
|
319
|
+
border-top: 1px solid var(--db-table-rule);
|
|
320
|
+
border-bottom: 1px solid var(--db-table-rule);
|
|
321
|
+
}
|
|
322
|
+
.slidev-layout.db-default tbody tr:nth-child(odd) {
|
|
323
|
+
background: var(--db-table-stripe); /* shade alternate data rows */
|
|
324
|
+
}
|
|
325
|
+
.slidev-layout.db-default tbody tr:last-child td {
|
|
326
|
+
border-bottom: 1px solid var(--db-table-rule);
|
|
327
|
+
}
|
|
328
|
+
/* Inline code inside tables AND headings: keep the syntax colors but drop the
|
|
329
|
+
gray "pill" background/padding so it reads like plain text. */
|
|
330
|
+
.slidev-layout.db-default th code,
|
|
331
|
+
.slidev-layout.db-default td code,
|
|
332
|
+
.slidev-layout.db-default h1 code,
|
|
333
|
+
.slidev-layout.db-default h2 code,
|
|
334
|
+
.slidev-layout.db-default h3 code {
|
|
335
|
+
background: transparent;
|
|
336
|
+
padding: 0;
|
|
337
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Custom transitions with a smooth slide and fade animation
|
|
3
|
+
* Far more subtle than the build-in
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* ```
|
|
7
|
+
* transition: slide-fade-left | slide-fade-right
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
.slide-fade-right-enter-active,
|
|
12
|
+
.slide-fade-left-enter-active {
|
|
13
|
+
transition:
|
|
14
|
+
opacity var(--slidev-transition-duration) ease
|
|
15
|
+
calc(var(--slidev-transition-duration) * 0.5), /* some additional delay here */
|
|
16
|
+
transform calc(var(--slidev-transition-duration) * 1.5) ease;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.slide-fade-right-leave-active,
|
|
20
|
+
.slide-fade-left-leave-active {
|
|
21
|
+
transition:
|
|
22
|
+
opacity var(--slidev-transition-duration) ease,
|
|
23
|
+
transform calc(var(--slidev-transition-duration) * 1.5) ease;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.slide-fade-right-leave-to,
|
|
27
|
+
.slide-fade-left-enter-from {
|
|
28
|
+
opacity: 0;
|
|
29
|
+
transform: translateX(4%);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.slide-fade-right-enter-from,
|
|
33
|
+
.slide-fade-left-leave-to {
|
|
34
|
+
opacity: 0;
|
|
35
|
+
transform: translateX(-4%);
|
|
36
|
+
}
|
package/styles/font.css
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
@font-face {
|
|
2
|
+
font-family: NotoSans;
|
|
3
|
+
src: url('../assets/fonts/NotoSans-VariableFont_wdth\,wght.ttf') format('truetype');
|
|
4
|
+
font-style: normal;
|
|
5
|
+
font-weight: 100 900;
|
|
6
|
+
font-stretch: 100%;
|
|
7
|
+
font-display: swap;
|
|
8
|
+
font-optical-sizing: auto;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@font-face {
|
|
12
|
+
font-family: NotoSans;
|
|
13
|
+
src: url('../assets/fonts/NotoSans-Italic-VariableFont_wdth\,wght.ttf') format('truetype');
|
|
14
|
+
font-style: italic;
|
|
15
|
+
font-weight: 100 900;
|
|
16
|
+
font-stretch: 100%;
|
|
17
|
+
font-display: swap;
|
|
18
|
+
font-optical-sizing: auto;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@font-face {
|
|
22
|
+
font-family: FiraCode;
|
|
23
|
+
src: url('../assets/fonts/FiraCode-VariableFont_wght.ttf') format('truetype');
|
|
24
|
+
font-style: normal;
|
|
25
|
+
font-weight: 300 700;
|
|
26
|
+
font-display: swap;
|
|
27
|
+
font-optical-sizing: auto;
|
|
28
|
+
}
|
package/styles/index.ts
ADDED
package/vite.config.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { createHighlighter } from 'shiki'
|
|
2
|
+
import { setupTableCaptions } from './markdown'
|
|
3
|
+
|
|
4
|
+
// Shipped WITH the theme: Slidev merges vite.config from every root (theme +
|
|
5
|
+
// addons + deck), so installing this theme is enough — no need to copy a file.
|
|
6
|
+
//
|
|
7
|
+
// Inline code syntax highlighting. Write inline code as: `{lang} the code`
|
|
8
|
+
// e.g. `{json} {"a": 1}`
|
|
9
|
+
// The leading `{lang}` token selects the language; everything after the first
|
|
10
|
+
// space is highlighted with Shiki and rendered inside a normal inline <code>.
|
|
11
|
+
//
|
|
12
|
+
// A deck can still override THEME, LANGS, or the rule by defining its own
|
|
13
|
+
// vite.config.ts (the deck's config merges last and wins).
|
|
14
|
+
//
|
|
15
|
+
// NB: no `import ... from 'vite'` here on purpose — `defineConfig` is only a
|
|
16
|
+
// type helper, and importing it would require `vite` to be resolvable from this
|
|
17
|
+
// file's location (it isn't, when the theme is loaded from its own directory).
|
|
18
|
+
const THEME = 'catppuccin-latte'
|
|
19
|
+
const LANGS = ['json', 'yaml', 'sql', 'c', 'cpp', 'python']
|
|
20
|
+
|
|
21
|
+
export default async () => {
|
|
22
|
+
const highlighter = await createHighlighter({ themes: [THEME], langs: LANGS })
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
slidev: {
|
|
26
|
+
markdown: {
|
|
27
|
+
// runs after Slidev's own markdown-it plugins, so our rule wins
|
|
28
|
+
markdownSetup(md: any) {
|
|
29
|
+
setupTableCaptions(md)
|
|
30
|
+
const fallback = md.renderer.rules.code_inline
|
|
31
|
+
md.renderer.rules.code_inline = (tokens: any[], idx: number, options: any, env: any, self: any) => {
|
|
32
|
+
const m = String(tokens[idx].content).match(/^\{([\w-]+)\}\s+([\s\S]+)$/)
|
|
33
|
+
if (m && highlighter.getLoadedLanguages().includes(m[1])) {
|
|
34
|
+
const inner = highlighter
|
|
35
|
+
.codeToHtml(m[2], { lang: m[1], theme: THEME })
|
|
36
|
+
.replace(/^<pre[^>]*><code[^>]*>/, '')
|
|
37
|
+
.replace(/<\/code><\/pre>\s*$/, '')
|
|
38
|
+
return `<code class="db-inline-code">${inner}</code>`
|
|
39
|
+
}
|
|
40
|
+
return fallback
|
|
41
|
+
? fallback(tokens, idx, options, env, self)
|
|
42
|
+
: self.renderToken(tokens, idx, options)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ASCII arrows -> unicode, in plain TEXT only. Code spans/blocks are
|
|
46
|
+
// separate token types, so SQL `->` / `->>` is never touched.
|
|
47
|
+
// Markdown's typographer turns `--` into an en-dash (`–`) before this
|
|
48
|
+
// runs, so we match the hyphen, en-dash and em-dash forms.
|
|
49
|
+
const DASH = '(?:--|–|—)' // -- or – or —
|
|
50
|
+
const reBoth = new RegExp(`<${DASH}>`, 'g')
|
|
51
|
+
const reRight = new RegExp(`${DASH}>`, 'g')
|
|
52
|
+
const reLeft = new RegExp(`<${DASH}`, 'g')
|
|
53
|
+
md.core.ruler.push('db-arrows', (state: any) => {
|
|
54
|
+
for (const tok of state.tokens) {
|
|
55
|
+
if (tok.type !== 'inline' || !tok.children) continue
|
|
56
|
+
for (const child of tok.children) {
|
|
57
|
+
if (child.type === 'text') {
|
|
58
|
+
child.content = child.content
|
|
59
|
+
.replace(reBoth, '↔')
|
|
60
|
+
.replace(reRight, '→')
|
|
61
|
+
.replace(reLeft, '←')
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
}
|