@farberg/reveal-template 1.1.19 → 1.1.21

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.
@@ -12,5 +12,10 @@ credits {
12
12
  }
13
13
 
14
14
  .reveal .slides {
15
- pointer-events: initial !important;
15
+ pointer-events: initial !important;
16
+ }
17
+
18
+ /* In print, drop the Simplemenu bar entirely. */
19
+ .menubar {
20
+ display: none !important;
16
21
  }
package/css/dhbw.css CHANGED
@@ -509,61 +509,154 @@ tr>tr:first-of-type {
509
509
  border-top: 1px solid black !important;
510
510
  }
511
511
 
512
- .reveal .slide-number {
513
- color: #4e565c;
514
- z-index: 100;
515
- }
512
+ /* ---------------------------------------------------------------------- */
513
+ /* Bottom strip: Simplemenu menubar (left), attribution (right of it), */
514
+ /* slide number (far right) — share one thin lane, same grey baseline. */
515
+ /* ---------------------------------------------------------------------- */
516
516
 
517
- .attribution {
518
- position: fixed !important;
519
- bottom: 0 !important;
520
- left: 0px !important;
521
- font-size: 12px !important;
517
+ :root {
518
+ --dhbw-strip-color: #4e565c;
519
+ --dhbw-strip-font-size: 12px;
520
+ --dhbw-strip-height: 20px;
521
+ --dhbw-strip-bottom: 6px;
522
522
  }
523
523
 
524
- .has-dark-background>.attribution {
525
- color: #4e565c;
524
+ .reveal .slide-number {
525
+ color: var(--dhbw-strip-color) !important;
526
+ background: none !important;
527
+ font-family: inherit !important;
528
+ font-size: var(--dhbw-strip-font-size) !important;
529
+ right: 8px !important;
530
+ bottom: var(--dhbw-strip-bottom) !important;
531
+ height: var(--dhbw-strip-height) !important;
532
+ line-height: var(--dhbw-strip-height) !important;
533
+ padding: 0 !important;
534
+ z-index: 100;
526
535
  }
527
536
 
528
- .has-dark-background>.attribution>a {
529
- color: #4e565c !important;
537
+ .reveal .slide-number a {
538
+ color: var(--dhbw-strip-color) !important;
539
+ opacity: 1 !important;
540
+ /* override Simplemenu's 0.33 dimming */
541
+ padding: 0 !important;
542
+ line-height: var(--dhbw-strip-height) !important;
530
543
  }
531
544
 
532
545
  credits {
533
546
  visibility: hidden;
534
547
  }
535
548
 
536
- /* Credits Dennis */
537
-
538
549
  attribution {
539
- position: absolute !important;
540
- /* display: block; */
541
- display: table-cell !important;
542
- vertical-align: middle !important;
543
- right: 35px;
544
- bottom: 8px;
545
- height: 22px;
550
+ position: fixed !important;
551
+ display: block !important;
552
+ left: auto;
553
+ right: 70px;
554
+ /* leaves room for the slide-number on its right */
555
+ bottom: var(--dhbw-strip-bottom) !important;
556
+ height: var(--dhbw-strip-height) !important;
557
+ line-height: var(--dhbw-strip-height) !important;
546
558
  z-index: 200;
547
- font-size: 12px;
559
+ font-size: var(--dhbw-strip-font-size) !important;
548
560
  text-align: right;
549
- color: #4e565c;
550
- background-color: rgba(0, 0, 0, 0.4);
561
+ color: var(--dhbw-strip-color) !important;
562
+ background-color: transparent !important;
563
+ padding: 0 !important;
551
564
  }
552
565
 
553
566
  attribution>span {
554
- padding-left: 5px !important;
555
- padding-right: 5px !important;
556
- line-height: 22px !important;
567
+ padding: 0 !important;
568
+ line-height: var(--dhbw-strip-height) !important;
557
569
  }
558
570
 
559
- attribution a {
560
- font-size: 12px;
561
- color: #4e565c;
571
+ attribution a,
572
+ attribution a:visited {
573
+ font-size: var(--dhbw-strip-font-size);
574
+ color: var(--dhbw-strip-color);
575
+ line-height: var(--dhbw-strip-height);
562
576
  }
563
577
 
564
- attribution a:visited {
565
- font-size: 12px;
566
- color: #4e565c;
578
+ .has-dark-background>.attribution,
579
+ .has-dark-background>.attribution>a {
580
+ color: var(--dhbw-strip-color) !important;
581
+ }
582
+
583
+ /* Simplemenu's CSS is injected at plugin load (after dhbw.css), so we
584
+ need !important here to win specificity on layout props. */
585
+ .menubar {
586
+ color: var(--dhbw-strip-color) !important;
587
+ background: transparent !important;
588
+ font-size: var(--dhbw-strip-font-size) !important;
589
+ height: var(--dhbw-strip-height) !important;
590
+ line-height: var(--dhbw-strip-height) !important;
591
+ bottom: var(--dhbw-strip-bottom) !important;
592
+ padding: 0 8px 0 15px !important;
593
+ /* left gutter for the menu */
594
+ justify-content: flex-start !important;
595
+ align-items: center !important;
596
+ }
597
+
598
+ .menubar:before,
599
+ .menubar:after {
600
+ display: none !important;
601
+ }
602
+
603
+ .menubar>ul {
604
+ gap: 1.5em !important;
605
+ margin: 0 !important;
606
+ padding: 0 !important;
607
+ justify-content: flex-start !important;
608
+ align-items: center !important;
609
+ height: var(--dhbw-strip-height) !important;
610
+ line-height: var(--dhbw-strip-height) !important;
611
+ }
612
+
613
+ .menubar>ul li {
614
+ display: inline-flex !important;
615
+ flex: 0 0 auto !important;
616
+ align-items: center !important;
617
+ height: var(--dhbw-strip-height) !important;
618
+ line-height: var(--dhbw-strip-height) !important;
619
+ padding: 0 !important;
620
+ margin: 0 !important;
621
+ }
622
+
623
+ /* Every menu link state — active, inactive, hover, visited — uses the same
624
+ color, size, weight, padding and rendering, so nothing can shift the
625
+ baseline between states. Hover is the only visual change. */
626
+ .menubar a,
627
+ .menubar a:visited,
628
+ .menubar a:active,
629
+ .menubar>ul a,
630
+ .menubar>ul li a.active,
631
+ .menubar>ul li.active a {
632
+ display: inline-block !important;
633
+ padding: 0 !important;
634
+ margin: 0 !important;
635
+ border: 0 !important;
636
+ text-decoration: none !important;
637
+ font-size: var(--dhbw-strip-font-size) !important;
638
+ font-weight: 400 !important;
639
+ font-style: normal !important;
640
+ color: var(--dhbw-strip-color) !important;
641
+ opacity: 1 !important;
642
+ height: var(--dhbw-strip-height) !important;
643
+ line-height: var(--dhbw-strip-height) !important;
644
+ vertical-align: baseline !important;
645
+ transform: none !important;
646
+ -webkit-font-smoothing: antialiased !important;
647
+ -moz-osx-font-smoothing: grayscale !important;
648
+ }
649
+
650
+ .menubar>ul a:hover {
651
+ color: #1a1a1a !important;
652
+ }
653
+
654
+ /* Active item: fake-bold via text-stroke so the glyph width stays identical
655
+ to the inactive state (font-weight changes would shift neighbour items). */
656
+ .menubar>ul li.active>a,
657
+ .menubar>ul li>a.active {
658
+ color: #1a1a1a !important;
659
+ -webkit-text-stroke: 0.4px currentColor !important;
567
660
  }
568
661
 
569
662
  .source-code-link {
@@ -1,7 +1,14 @@
1
+ <!-- .slide: data-state="hide-menubar" -->
1
2
  <div class="lecturetitle">Introduction</div>
2
3
 
3
4
  ---
4
- ## Some Heading
5
+ ## Table of Contents
6
+ <!-- .slide: data-state="hide-menubar" -->
7
+
8
+ <ul class="menu"><ul>
9
+
10
+ ---
11
+ ## Mermaid Example
5
12
 
6
13
  ```mermaid
7
14
  graph LR
@@ -15,13 +22,16 @@ Some text
15
22
  - This is an example presentation
16
23
  - This is an example presentation
17
24
 
18
- Some text
19
- - This is an example presentation
20
- - This is an example presentation
21
- - This is an example presentation
25
+ ---
26
+ ## Asciinema Example
27
+
28
+ <asciinema data-conf='{ "cols": 120, "rows": 25, "theme":"monokai", "autoPlay": true, "idleTimeLimit": 2, "terminalFontSize": "16px"}'
29
+ src="k8s-deployment.cast" />
30
+
22
31
 
23
32
  ---
24
- ## Next Heading
33
+ ## Some Heading
34
+ <!-- .slide: data-name="Some Heading" -->
25
35
 
26
36
  Some text
27
37
  - This is an example presentation
@@ -33,9 +43,11 @@ Some text
33
43
  - This is an example presentation
34
44
  - This is an example presentation
35
45
 
46
+ <credits>This is a test for the credits section.</credits>
36
47
 
37
48
  ---
38
49
  ## Next Heading
50
+ <!-- .slide: data-name="next-heading" -->
39
51
 
40
52
  Some text
41
53
  - This is an example presentation
@@ -0,0 +1,94 @@
1
+ {"version": 2, "width": 130, "height": 26, "timestamp": 1584010118, "idle_time_limit": 2.0, "env": {"SHELL": "/usr/local/bin/bash", "TERM": "xterm-256color"}}
2
+ [0.015142, "o", "\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1006l\u001b[?1005l\u001b[c\u001b(B\u001b[m\u001b[?12;25h\u001b[?12l\u001b[?25h\u001b[?1003l\u001b[?1006l\u001b[?2004l\u001b[1;1H\u001b[1;26r\u001b]112\u0007\u001b[21;17H\u001b[?1006h\u001b[?1002h"]
3
+ [0.016013, "o", "\u001b[20;1H──────────────────────────────────────────────────────────────────\u001b[32m────────────────────────────────────────────────────────────────\u001b[?25l\u001b(B\u001b[m\u001b[1;1Hdennis@dppro:~$ \u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[2Bdennis@dppro:~$ \u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[21;17H\u001b[?12l\u001b[?25h"]
4
+ [0.016133, "o", "\u001b(B\u001b[m\u001b[?12;25h\u001b[?12l\u001b[?25h\u001b[?1003l\u001b[?1006l\u001b[?2004l\u001b[1;1H\u001b[1;26r\u001b[21;17H\u001b[?1006h\u001b[?1002h\u001b[20;1H──────────────────────────────────────────────────────────────────\u001b[32m────────────────────────────────────────────────────────────────\u001b[?25l\u001b(B\u001b[m\u001b[1;1Hdennis@dppro:~$ \u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[2Bdennis@dppro:~$ \u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[21;17H\u001b[?12l\u001b[?25h"]
5
+ [4.901951, "o", "watch -t kubectl get deployment"]
6
+ [5.428202, "o", "\r\n"]
7
+ [5.503769, "o", "\u001b[?25l\u001b[ANo resources found in default namespace.\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[129C\u001b[?12l\u001b[?25h"]
8
+ [11.899887, "o", "\u001b[32m\u001b[20;1H──────────────────────────────────────────────────────────────────\u001b[39m────────────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[1;17H"]
9
+ [12.619999, "o", "kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml"]
10
+ [13.263125, "o", "\r\n"]
11
+ [13.772043, "o", "deployment.apps/nginx-deployment created\r\n"]
12
+ [13.788565, "o", "\u001b[21dNAME READY UP-TO-DATE AVAILABLE AGE\r\nnginx-deployment 0/3 0\u001b[12C0\u001b[3;1H\u001b[22;53H0s\u001b[3;1H"]
13
+ [13.801261, "o", "dennis@dppro:~$ "]
14
+ [15.855941, "o", "\u001b[22;20H3\u001b[7C3\u001b[12C3\u001b[11C2\u001b[3;17H"]
15
+ [17.924864, "o", "\u001b[22;53H4\u001b[3;17H"]
16
+ [19.101477, "o", "kubectl get replicaset"]
17
+ [19.886126, "o", "\r\n"]
18
+ [19.956142, "o", "NAME DESIRED CURRENT READY AGE\r\nnginx-deployment-54f57cf6bf 3 3 3 6s\r\n"]
19
+ [19.976361, "o", "dennis@dppro:~$ "]
20
+ [19.99448, "o", "\u001b[22;53H6\u001b[6;17H"]
21
+ [22.068487, "o", "\u001b[22;53H8\u001b[6;17H"]
22
+ [24.14261, "o", "\u001b[22;53H10s\u001b[6;17H"]
23
+ [24.420512, "o", "kubectl get pods"]
24
+ [24.992778, "o", "\r\n"]
25
+ [25.265619, "o", "NAME READY STATUS RESTARTS AGE\r\nnginx-deployment-54f57cf6bf-566ql 1/1 Running 0 11s\r\nnginx-deployment-54f57cf6bf-ch68t 1/1 Running 0 11s\r\nnginx-deployment-54f57cf6bf-skf22 1/1 Running 0 11s"]
26
+ [25.265954, "o", "\r\n"]
27
+ [25.289406, "o", "dennis@dppro:~$ "]
28
+ [26.209228, "o", "\u001b[22;54H2\u001b[11;17H"]
29
+ [28.278645, "o", "\u001b[22;54H4\u001b[11;17H"]
30
+ [30.345443, "o", "\u001b[22;54H6\u001b[11;17H"]
31
+ [32.411563, "o", "\u001b[22;54H8\u001b[11;17H"]
32
+ [33.955998, "o", "kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 --record"]
33
+ [34.481068, "o", "\u001b[22;53H20\u001b[11;89H"]
34
+ [35.908815, "o", "\r\n"]
35
+ [35.974804, "o", "deployment.apps/nginx-deployment image updated\r\n"]
36
+ [35.998725, "o", "dennis@dppro:~$ "]
37
+ [36.253922, "o", "kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 --record"]
38
+ [36.447497, "o", "\u001b[25Gget pods\u001b[K"]
39
+ [36.554676, "o", "\u001b[22;28H1\u001b[25C2\u001b[13;33H"]
40
+ [37.3226, "o", "\r\n"]
41
+ [37.386231, "o", "NAME READY STATUS RESTARTS AGE\r\nnginx-deployment-54f57cf6bf-566ql 1/1 Running 0 23s\r\nnginx-deployment-54f57cf6bf-ch68t 1/1 Terminating 0 23s"]
42
+ [37.386427, "o", "\u001b[1;19r\u001b[19;1H\n\u001b[3Anginx-deployment-54f57cf6bf-skf22 1/1 Running 0 23s\r\nnginx-deployment-56f8998dbc-6s8xb 0/1 ContainerCreating 0 0s\r\nnginx-deployment-56f8998dbc-qctt9 1/1 Running 0 1s\u001b[1;26r\u001b[19;1H"]
43
+ [37.405538, "o", "dennis@dppro:~$ "]
44
+ [38.615804, "o", "\u001b[22;28H3\u001b[25C4\u001b[19;17H"]
45
+ [40.048096, "o", "kubectl get pods"]
46
+ [40.229233, "o", "\u001b[8Dset image deployment/nginx-deployment nginx=nginx:1.9.1 --record"]
47
+ [40.608258, "o", "\u001b[25Gget pods\u001b[K"]
48
+ [40.679253, "o", "\u001b[22;54H6\u001b[19;33H"]
49
+ [41.059858, "o", "\u001b[4Dreplicaset"]
50
+ [41.665878, "o", "\u001b[1;19r\u001b[19;1H\n\u001b[1;26r\u001b[19;1H"]
51
+ [41.729691, "o", "\u001b[1;19r\u001b[2S\u001b[17dNAME DESIRED CURRENT READY AGE\r\nnginx-deployment-54f57cf6bf 0 0 0 28s\r\nnginx-deployment-56f8998dbc 3 3 \u001b[1;26r\u001b[19;51H\u001b[1;19r\u001b[19;1H\n\u001b[18;51H3 6s\u001b[1;26r\u001b[19;1H"]
52
+ [41.747295, "o", "dennis@dppro:~$ "]
53
+ [42.747218, "o", "\u001b[22;54H9\u001b[19;17H"]
54
+ [44.812612, "o", "\u001b[22;53H31\u001b[19;17H"]
55
+ [46.880279, "o", "\u001b[22;54H3\u001b[19;17H"]
56
+ [48.954986, "o", "\u001b[22;54H5\u001b[19;17H"]
57
+ [50.65087, "o", "kubectl scale deployment.v1.apps/nginx-deployment --replicas=2"]
58
+ [51.028781, "o", "\u001b[22;54H7\u001b[19;79H"]
59
+ [51.330372, "o", "\u001b[1;19r\u001b[19;1H\n\u001b[1;26r\u001b[19;1H"]
60
+ [51.405333, "o", "\u001b[1;19r\u001b[19;1H\n\u001b[Adeployment.apps/nginx-deployment scaled\u001b[1;26r\u001b[19;1H"]
61
+ [51.437681, "o", "dennis@dppro:~$ "]
62
+ [51.712471, "o", "kubectl scale deployment.v1.apps/nginx-deployment --replicas=2"]
63
+ [51.872287, "o", "\u001b[25Gget replicaset\u001b[K"]
64
+ [52.297278, "o", "\u001b[10D\u001b[6Ppods"]
65
+ [52.758532, "o", "\u001b[1;19r\u001b[19;1H\n\u001b[1;26r\u001b[19;1H"]
66
+ [52.822498, "o", "\u001b[1;19r\u001b[2S\u001b[17dNAME READY STATUS RESTARTS AGE\r\nnginx-deployment-56f8998dbc-6s8xb 1/1 Running 0 16s\r\nnginx-deployment-56f8998dbc-gbkvj 0/1 Terminating 0\u001b[1;26r\u001b[19;60H\u001b[1;19r\u001b[2S\u001b[17;60H 15s\r\nnginx-deployment-56f8998dbc-qctt9 1/1 Running 0 17s\u001b[1;26r\u001b[19;1H"]
67
+ [52.839425, "o", "dennis@dppro:~$ "]
68
+ [53.102219, "o", "\u001b[22;20H2/2 2\u001b[12C2\u001b[12C9\u001b[19;17H"]
69
+ [55.167659, "o", "\u001b[22;53H41\u001b[19;17H"]
70
+ [57.230776, "o", "\u001b[22;54H3\u001b[19;17H"]
71
+ [57.765264, "o", "kubectl get pods"]
72
+ [58.10153, "o", "\u001b[1;19r\u001b[19;1H\n\u001b[1;26r\u001b[19;1H"]
73
+ [58.171476, "o", "\u001b[1;19r\u001b[2S\u001b[17dNAME READY STATUS RESTARTS AGE\r\nnginx-deployment-56f8998dbc-6s8xb 1/1 Running 0 21s\r\nnginx-deployment-56f8998dbc-qctt9 1/1 Running 0 22s\u001b[1;26r\u001b[19;69H\u001b[1;19r\u001b[19;1H\n\u001b[1;26r\u001b[19;1H"]
74
+ [58.192559, "o", "dennis@dppro:~$ "]
75
+ [59.301196, "o", "\u001b[22;54H5\u001b[19;17H"]
76
+ [59.880721, "o", "kubectl get pods"]
77
+ [60.419891, "o", "\u001b[8Dscale deployment.v1.apps/nginx-deployment --replicas=2"]
78
+ [60.850326, "o", "\u001b[25Gget replicaset\u001b[K"]
79
+ [61.369231, "o", "\u001b[22;54H7\u001b[19;39H"]
80
+ [61.409873, "o", "\u001b[1;19r\u001b[19;1H\n\u001b[1;26r\u001b[19;1H"]
81
+ [61.482126, "o", "\u001b[1;19r\u001b[3S\u001b[16dNAME DESIRED CURRENT READY AGE\r\nnginx-deployment-54f57cf6bf 0 0 0 47s\r\nnginx-deployment-56f8998dbc 2 2 2 25s\u001b[1;26r\u001b[19;1H"]
82
+ [61.482302, "o", "\u001b[32m\r\n──────────────────────────────────────────────────────────────────\u001b[39m────────────────────────────────────────────────────────────────\u001b[?25l\u001b(B\u001b[m\u001b[1;1HNAME DESIRED CURRENT READY AGE\u001b[K\r\nnginx-deployment-54f57cf6bf 0 0 0 28s\u001b[K\r\nnginx-deployment-56f8998dbc 3 3 3 6s\u001b[K\r\ndennis@dppro:~$ kubectl scale deployment.v1.apps/nginx-deployment --replicas=2\u001b[K\r\ndeployment.apps/nginx-deployment scaled\u001b[K\r\ndennis@dppro:~$ kubectl get pods\u001b[K\r\nNAME READY STATUS RESTARTS AGE\u001b[K\r\nnginx-deployment-56f8998dbc-6s8xb 1/1 Running 0 16s\u001b[K\r\nnginx-deployment-56f8998dbc-gbkvj 0/1 Terminating 0 15s\u001b[K\r\nnginx-deploy"]
83
+ [61.482398, "o", "ment-56f8998dbc-qctt9 1/1 Running 0 17s\u001b[K\r\ndennis@dppro:~$ kubectl get pods\u001b[K\r\nNAME READY STATUS RESTARTS AGE\u001b[K\r\nnginx-deployment-56f8998dbc-6s8xb 1/1 Running 0 21s\u001b[K\r\nnginx-deployment-56f8998dbc-qctt9 1/1 Running 0 22s\u001b[K\r\ndennis@dppro:~$ kubectl get replicaset\u001b[K\r\nNAME DESIRED CURRENT READY AGE\u001b[K\r\nnginx-deployment-54f57cf6bf 0 0 0 47s\u001b[K\r\nnginx-deployment-56f8998dbc 2 2 2 25s\u001b[K\r\n\u001b[K\u001b[2BNAME READY UP-TO-DATE AVAILABLE AGE\u001b[K\r\nnginx-deployment 2/2 2\u001b[12X\u001b[12C2\u001b[11X\u001b[11C47s\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[7A\u001b[?12l\u001b[?25h"]
84
+ [61.503534, "o", "dennis@dppro:~$ "]
85
+ [62.726195, "o", "kubectl get replicaset"]
86
+ [62.997892, "o", "\u001b[10D\u001b[6Ppods"]
87
+ [63.438894, "o", "\u001b[22;54H9\u001b[19;33H"]
88
+ [64.144609, "o", "\u001b[1;19r\u001b[19;1H\n\u001b[1;26r\u001b[19;1H"]
89
+ [64.205435, "o", "\u001b[1;19r\u001b[2S\u001b[17dNAME READY STATUS RESTARTS AGE\r\nnginx-deployment-56f8998dbc-6s8xb 1/1 Running 0 27s\r\nnginx-deployment-56f8998dbc-qctt9 1/1 Running 0 \u001b[1;26r\u001b[19;66H\u001b[1;19r\u001b[19;1H\n\u001b[18;66H28s"]
90
+ [64.205618, "o", "\u001b[1;26r\u001b[19;1H"]
91
+ [64.225166, "o", "dennis@dppro:~$ "]
92
+ [65.503262, "o", "\u001b[22;53H51\u001b[19;17H"]
93
+ [67.57642, "o", "\u001b[22;54H3\u001b[19;17H"]
94
+ [67.845157, "o", "\u001b[1;26r\u001b(B\u001b[m\u001b[?1l\u001b>\u001b[H\u001b[2J\u001b]112\u0007\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1006l\u001b[?1005l\u001b[?1049l\u001b[23;0;0t"]
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE html>
1
2
  <html>
2
3
 
3
4
  <head>
@@ -8,13 +9,27 @@
8
9
  <meta name="viewport"
9
10
  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes, minimal-ui">
10
11
 
12
+ <!--
13
+ Local-dev variant using an import map so the JS imports the package by its
14
+ bare specifier ("@farberg/reveal-template/init-reveal.js") rather than a
15
+ relative path. This mirrors how a bundler (Vite, Rollup) resolves it, and
16
+ makes migration to a bundler a no-op for this file.
17
+
18
+ The import map remaps the bare prefix to "../" (the repo root, since
19
+ this HTML lives in docs/). basePath stays "../" because that's where
20
+ node_modules lives relative to this document.
21
+ -->
22
+ <script type="importmap">
23
+ {
24
+ "imports": {
25
+ "@farberg/reveal-template/": "../"
26
+ }
27
+ }
28
+ </script>
11
29
  <script type="module">
12
- import { initReveal } from '../init-reveal.js'
30
+ import { initReveal } from '@farberg/reveal-template/init-reveal.js'
13
31
  initReveal({
14
- jsPrefixPath: "../",
15
- cssPrefixPath: "../",
16
- cssThemePrefixPath: "../",
17
- revealPath: "../node_modules/reveal.js/",
32
+ basePath: "../",
18
33
  verbose: true
19
34
  });
20
35
  </script>
@@ -23,10 +38,6 @@
23
38
  <body>
24
39
  <div class="reveal">
25
40
  <div class="slides">
26
- <section data-markdown>
27
- <textarea data-template>
28
- </textarea>
29
- </section>
30
41
  </div>
31
42
  </div>
32
43
  </body>
package/docs/npm.html CHANGED
@@ -1,3 +1,4 @@
1
+ <!DOCTYPE html>
1
2
  <html>
2
3
 
3
4
  <head>
@@ -7,17 +8,23 @@
7
8
  <meta name="viewport"
8
9
  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes, minimal-ui">
9
10
 
10
- <link rel="stylesheet" href="node_modules/reveal.js/dist/reveal.css">
11
- <link rel="stylesheet" href="node_modules/reveal.js/plugin/highlight/zenburn.css">
12
- <link rel="stylesheet" href="node_modules/@farberg/reveal-template/css/dhbw.css" id="theme">
11
+ <!--
12
+ In a real slides project that installs @farberg/reveal-template via npm,
13
+ your HTML sits next to node_modules/ and the boilerplate is just:
13
14
 
15
+ <script type="module">
16
+ import { initReveal } from './node_modules/@farberg/reveal-template/init-reveal.js'
17
+ initReveal()
18
+ </script>
19
+
20
+ The example below mirrors that, but inside this repo: init-reveal.js is
21
+ one directory up (../init-reveal.js) and so is node_modules (basePath: "../").
22
+ Stylesheets are added by init-reveal.js; no <link> tags needed here.
23
+ -->
14
24
  <script type="module">
15
25
  import { initReveal } from '../init-reveal.js'
16
26
  initReveal({
17
- jsPrefixPath: "../",
18
- cssPrefixPath: "../",
19
- cssThemePrefixPath: "../",
20
- revealPath: "../node_modules/reveal.js/",
27
+ basePath: "../",
21
28
  verbose: true
22
29
  });
23
30
  </script>
package/init-reveal.js CHANGED
@@ -11,47 +11,75 @@ import DirTreePlugin from './plugins/reveal-plugin-dir-tree.js';
11
11
  import PrefixUrlPlugin from './plugins/reveal-plugin-prefix-with-base-url.js';
12
12
  import AsciinemaPlugin from './plugins/reveal-plugin-asciinema.js';
13
13
 
14
- const defaultOptions = {
15
- revealOptions: {},
16
- revealPath: "../../reveal.js/",
17
- jsPrefixPath: "",
18
- cssPrefixPath: "",
19
- cssThemePrefixPath: "node_modules/@farberg/reveal-template/",
20
- slidesDestinationElement: document.querySelector("body div.reveal div.slides"),
21
- indexDocument: "00 - Introduction.md",
22
- verbose: false
14
+ // All third-party paths below are written as bare-package specifiers
15
+ // (e.g. "reveal.js/dist/reveal.mjs"). At runtime they are resolved to
16
+ // `${basePath}node_modules/${pkgPath}`. When migrating to a bundler
17
+ // (Vite, etc.), these same strings can be used directly as import
18
+ // specifiers — drop the toUrl() prefixing and they Just Work.
19
+
20
+ const revealEsmModules = [
21
+ 'reveal.js/dist/reveal.mjs', // must be first
22
+ 'reveal.js/dist/plugin/markdown.mjs',
23
+ 'reveal.js/dist/plugin/highlight.mjs',
24
+ 'reveal.js/dist/plugin/search.mjs',
25
+ 'reveal.js/dist/plugin/notes.mjs',
26
+ 'reveal.js/dist/plugin/math.mjs',
27
+ 'reveal.js/dist/plugin/zoom.mjs'
28
+ ]
29
+
30
+ // Third-party ESM deps loaded dynamically via import(). Awaited in parallel.
31
+ // `isPlugin: true` means the module's default export is a Reveal plugin and
32
+ // gets registered automatically; otherwise it's a library injected into a
33
+ // Dennis-plugin factory (see buildDennisPlugins).
34
+ const esmDeps = {
35
+ qrCreator: { path: 'qr-creator/dist/qr-creator.es6.min.js' },
36
+ fflate: { path: 'fflate/esm/browser.js' },
37
+ asciinemaPlayer: { path: 'asciinema-player/dist/index.js' },
38
+ revealMermaid: { path: 'reveal.js-mermaid-plugin/plugin/mermaid/mermaid.esm.js', isPlugin: true },
39
+ simplemenu: { path: 'reveal.js-simplemenu/plugin/simplemenu/simplemenu.esm.js', isPlugin: true }
23
40
  }
24
41
 
42
+ // Classic-script deps that publish themselves on `window` and have no ESM build.
43
+ // These are awaited via the script `load` event so their globals are defined
44
+ // before Reveal.initialize is called.
25
45
  const externalJsLibs = [
26
- 'node_modules/easyqrcodejs/dist/easy.qrcode.min.js',
27
- 'node_modules/file-saver/dist/FileSaver.min.js',
28
- 'node_modules/jszip/dist/jszip.min.js',
29
- 'node_modules/asciinema-player/dist/bundle/asciinema-player.min.js',
30
- 'node_modules/reveal.js-plugins/customcontrols/plugin.js',
31
- 'node_modules/reveal.js-plugins/chalkboard/plugin.js',
32
- 'node_modules/@fortawesome/fontawesome-free/js/all.min.js',
33
- 'node_modules/reveal.js-mermaid-plugin/plugin/mermaid/mermaid.js'
46
+ 'reveal.js-plugins/customcontrols/plugin.js', // → window.RevealCustomControls
47
+ 'reveal.js-plugins/chalkboard/plugin.js' // → window.RevealChalkboard
34
48
  ]
35
49
 
36
50
  const extraStylesheets = [
37
- { href: 'node_modules/reveal.js/dist/reveal.css' },
38
- { href: 'node_modules/reveal.js/dist/plugin/highlight/zenburn.css' },
39
- { href: 'node_modules/asciinema-player/dist/bundle/asciinema-player.css' },
40
- { href: 'node_modules/reveal.js-plugins/customcontrols/style.css' },
41
- { href: 'node_modules/reveal.js-plugins/chalkboard/style.css' },
42
- { href: 'node_modules/@fortawesome/fontawesome-free/css/all.min.css' },
51
+ { href: 'reveal.js/dist/reveal.css' },
52
+ { href: 'reveal.js/dist/plugin/highlight/zenburn.css' },
53
+ { href: 'asciinema-player/dist/bundle/asciinema-player.css' },
54
+ { href: 'reveal.js-plugins/customcontrols/style.css' },
55
+ { href: 'reveal.js-plugins/chalkboard/style.css' },
56
+ { href: '@fortawesome/fontawesome-free/css/all.min.css' }
43
57
  ]
44
58
 
45
- const extraThemeCssStylesheets = [
46
- { href: 'css/dhbw.css', id: 'theme' }
47
-
59
+ // Package-owned assets (theme + print CSS) live inside this package, NOT under
60
+ // node_modules. They're always co-located with init-reveal.js in local dev
61
+ // that's the repo root, in an npm install it's node_modules/@farberg/reveal-template/.
62
+ // Resolving against import.meta.url handles both cases identically and is the
63
+ // standard bundler-friendly pattern for package assets.
64
+ const defaultThemeCss = [
65
+ { href: new URL('./css/dhbw.css', import.meta.url).href, id: 'theme' }
48
66
  ]
49
67
 
50
- const defaultDennisPlugins = [
51
- ShowCodeSnippets, ShowToc, ShowAttribution, ShowQrCode, ShowTitle,
52
- ModifyFontSize, ShowHTMLExample, ToggleSolutionsPlugin, DirTreePlugin,
53
- PrefixUrlPlugin, AsciinemaPlugin
54
- ]
68
+ const printStylesheet = new URL('./css/dhbw-print.css', import.meta.url).href
69
+
70
+ const defaultOptions = {
71
+ revealOptions: {},
72
+ // Path prefix to the directory containing node_modules/, relative to the HTML.
73
+ // Examples: "" (HTML next to node_modules), "../" (HTML one level down).
74
+ basePath: "",
75
+ // Theme stylesheets. Defaults to this package's dhbw.css (resolved against
76
+ // import.meta.url so it works in both local-dev and npm-install layouts).
77
+ // Override with absolute or document-relative URLs to swap themes.
78
+ themeCss: defaultThemeCss,
79
+ slidesDestinationElement: document.querySelector("body div.reveal div.slides"),
80
+ indexDocument: "00 - Introduction.md",
81
+ verbose: false
82
+ }
55
83
 
56
84
  const defaultRevealOptions = {
57
85
  embedded: false,
@@ -60,7 +88,7 @@ const defaultRevealOptions = {
60
88
  // Display a presentation progress bar
61
89
  progress: true,
62
90
  // Display the page number of the current slide
63
- slideNumber: true,
91
+ slideNumber: "c/t",
64
92
  // Push each slide change to the browser history
65
93
  history: true,
66
94
  // none/fade/slide/convex/concave/zoom
@@ -92,6 +120,13 @@ const defaultRevealOptions = {
92
120
  { color: 'rgba(100,100,100,0.6)' },
93
121
  ]
94
122
  },
123
+ simplemenu: {
124
+ flat: true,
125
+ barhtml: {
126
+ header: "",
127
+ footer: "<div class='menubar bottom'><ul class='menu'></ul></div>"
128
+ }
129
+ },
95
130
  keyboard: {
96
131
  33: function () { Reveal.left(); }, // Don't go up using the presenter
97
132
  34: function () { Reveal.right(); }, // Don't go down using the presenter
@@ -119,81 +154,108 @@ const defaultRevealOptions = {
119
154
  secondaryColor: '#5c6971',
120
155
  secondaryTextColor: '#000'
121
156
  },
122
- sequence: { mirrorActors: false, useMaxWidth: true },
123
- flowchart: { useMaxWidth: true, padding: 6 }
157
+ sequence: {
158
+ mirrorActors: false,
159
+ useMaxWidth: true,
160
+ boxMargin: 15,
161
+ actorMargin: 60,
162
+ messageMargin: 45,
163
+ noteMargin: 15
164
+ },
165
+ flowchart: {
166
+ useMaxWidth: true,
167
+ htmlLabels: true,
168
+ curve: 'basis',
169
+ padding: 20,
170
+ nodeSpacing: 70,
171
+ rankSpacing: 90,
172
+ subGraphTitleMargin: { top: 8, bottom: 8 }
173
+ }
124
174
  },
125
175
 
126
176
  // Leave here
127
177
  plugins: []
128
178
  }
129
179
 
130
- async function addPrintStylesheetIfUrlContainsPrintPdf() {
131
- // If the query includes 'print-pdf', include the PDF print sheet
132
- if (window.location.search.match(/print-pdf/gi)) {
133
- console.log("Print version requested");
180
+ // Resolve a bare-package path against the configured basePath, and
181
+ // absolutize against document.baseURI so the result works identically
182
+ // for DOM tag URLs (resolved vs document) and dynamic import()
183
+ // (resolved vs the importing module URL).
184
+ function toUrl(basePath, pkgPath) {
185
+ return new URL(`${basePath}node_modules/${pkgPath}`, document.baseURI).href
186
+ }
134
187
 
135
- const link = document.createElement('link');
136
- link.rel = 'stylesheet';
137
- link.type = 'text/css';
138
- link.href = 'node_modules/@farberg/reveal-template/css/dhbw-print.css';
139
- document.getElementsByTagName('head')[0].appendChild(link);
140
- }
188
+ async function addPrintStylesheetIfUrlContainsPrintPdf(options) {
189
+ if (!window.location.search.match(/print-pdf/gi)) return
190
+
191
+ console.log("Print version requested")
192
+ const link = document.createElement('link')
193
+ link.rel = 'stylesheet'
194
+ link.type = 'text/css'
195
+ link.href = printStylesheet
196
+ document.head.appendChild(link)
141
197
  }
142
198
 
143
199
  // Resolve when window has finished loading
144
200
  function windowOnLoadPromise() {
145
- return new Promise((resolve, reject) => {
146
- window.addEventListener('load', () => resolve())
147
- })
201
+ return new Promise(resolve => window.addEventListener('load', () => resolve()))
148
202
  }
149
203
 
150
- // Load reveal and its plugins
204
+ // Load reveal core + bundled plugins
151
205
  function loadRevealAndPlugins(options) {
152
- const imports = [
153
- "dist/reveal.mjs" /*must be the first one*/,
154
- "dist/plugin/markdown.mjs",
155
- "dist/plugin/highlight.mjs",
156
- "dist/plugin/search.mjs",
157
- "dist/plugin/notes.mjs",
158
- "dist/plugin/math.mjs",
159
- "dist/plugin/zoom.mjs"
160
- ]
161
-
162
206
  if (options.verbose)
163
- console.log("Importing the following plugins: ", imports)
207
+ console.log("Importing reveal modules: ", revealEsmModules)
164
208
 
165
- return Promise.all(imports.map(i => import(options.revealPath + i)))
209
+ return Promise.all(revealEsmModules.map(p => import(toUrl(options.basePath, p))))
166
210
  }
167
211
 
168
- // Add js tags to the header and resolve
169
- async function addJsDependencies(options, externalJsLibs) {
170
- for (let file of externalJsLibs) {
171
- const script = document.createElement('script');
172
- script.src = options.jsPrefixPath + file;
173
- document.head.appendChild(script);
212
+ // Dynamically import each third-party ESM dep. Returns an object keyed by the
213
+ // same names as `esmDeps`, mapped to the imported module namespace.
214
+ // Dynamically import each esmDep in parallel. Returns:
215
+ // { deps: { [name]: module }, plugins: [defaultExports of isPlugin entries] }
216
+ async function loadEsmDeps(options) {
217
+ const loaded = await Promise.all(
218
+ Object.entries(esmDeps).map(async ([key, meta]) => {
219
+ const mod = await import(toUrl(options.basePath, meta.path))
220
+ return { key, mod, meta }
221
+ })
222
+ )
223
+ return {
224
+ deps: Object.fromEntries(loaded.map(({ key, mod }) => [key, mod])),
225
+ plugins: loaded.filter(({ meta }) => meta.isPlugin).map(({ mod }) => mod.default)
174
226
  }
175
227
  }
176
228
 
177
- // Add CSSs tags to the header and resolve
178
- async function addCssDependencies(options, cssFiles, themeCssFiles) {
229
+ // Inject classic <script> tags and await each one's load event so dependent
230
+ // globals (window.RevealChalkboard, etc.) are defined before Reveal init.
231
+ function addJsDependencies(options) {
232
+ return Promise.all(externalJsLibs.map(pkgPath => new Promise((resolve, reject) => {
233
+ const script = document.createElement('script')
234
+ script.src = toUrl(options.basePath, pkgPath)
235
+ script.onload = () => resolve()
236
+ script.onerror = () => reject(new Error(`Failed to load ${script.src}`))
237
+ document.head.appendChild(script)
238
+ })))
239
+ }
240
+
241
+ // Add <link rel="stylesheet"> tags for each CSS file
242
+ function addCssDependencies(options) {
179
243
  function addCssElement(href, id) {
180
- const cssEl = document.createElement('link');
244
+ const cssEl = document.createElement('link')
181
245
  cssEl.rel = "stylesheet"
182
246
  cssEl.href = href
183
- if (id)
184
- cssEl.id = id
185
-
186
- document.head.appendChild(cssEl);
247
+ if (id) cssEl.id = id
248
+ document.head.appendChild(cssEl)
187
249
  }
188
250
 
189
- for (let css of cssFiles) {
190
- addCssElement(options.cssPrefixPath + css.href, css.id)
191
- }
192
-
193
- for (let css of themeCssFiles) {
194
- addCssElement(options.cssThemePrefixPath + css.href, css.id)
195
- }
251
+ for (const css of extraStylesheets)
252
+ addCssElement(toUrl(options.basePath, css.href), css.id)
196
253
 
254
+ // Theme CSS hrefs are used as-is. Defaults are absolute URLs (resolved via
255
+ // import.meta.url so they work in both local-dev and npm-install layouts).
256
+ // User overrides pass document-relative or absolute URLs directly.
257
+ for (const css of options.themeCss)
258
+ addCssElement(css.href, css.id)
197
259
  }
198
260
 
199
261
  function getDocumentToLoadOrRedirectToIndexDocument(options) {
@@ -221,6 +283,24 @@ function addMarkdownSectionToPresentation(doc, options) {
221
283
  options.slidesDestinationElement.appendChild(mdel)
222
284
  }
223
285
 
286
+ // Build the Dennis-plugins array, injecting ESM deps into the factories that
287
+ // need them. Plugins that take no deps stay as static factory imports.
288
+ function buildDennisPlugins(deps) {
289
+ return [
290
+ ShowCodeSnippets,
291
+ ShowToc,
292
+ ShowAttribution,
293
+ ShowQrCode(deps.qrCreator.default),
294
+ ShowTitle,
295
+ ModifyFontSize,
296
+ ShowHTMLExample,
297
+ ToggleSolutionsPlugin,
298
+ DirTreePlugin(deps.fflate),
299
+ PrefixUrlPlugin,
300
+ AsciinemaPlugin(deps.asciinemaPlayer.create)
301
+ ]
302
+ }
303
+
224
304
  export function initReveal(opts) {
225
305
  // Generate options and include defaults (later sources' properties overwrite earlier ones)
226
306
  const options = Object.assign({}, defaultOptions, opts)
@@ -228,19 +308,22 @@ export function initReveal(opts) {
228
308
  // Load dependencies and then initialize Reveal
229
309
  Promise.all([
230
310
  loadRevealAndPlugins(options),
231
- addJsDependencies(options, externalJsLibs),
232
- addCssDependencies(options, extraStylesheets, extraThemeCssStylesheets),
233
- addPrintStylesheetIfUrlContainsPrintPdf(),
311
+ loadEsmDeps(options),
312
+ addJsDependencies(options),
313
+ addCssDependencies(options),
314
+ addPrintStylesheetIfUrlContainsPrintPdf(options),
234
315
  windowOnLoadPromise()
235
316
  ]).then(async values => {
236
- //Get the first element from the array, this is the Reveal module
237
- const modules = values[0].map(m => m.default)
238
- const Reveal = modules.shift();
317
+ const [revealModules, { deps, plugins: esmPlugins }] = values
318
+
319
+ // First entry from reveal modules is Reveal itself
320
+ const modules = revealModules.map(m => m.default)
321
+ const Reveal = modules.shift()
239
322
 
240
- //Make it globally available
323
+ // Make it globally available
241
324
  window.Reveal = Reveal
242
325
 
243
- //Add markdown doc to presentation
326
+ // Add markdown doc to presentation
244
327
  const doc = getDocumentToLoadOrRedirectToIndexDocument(options)
245
328
 
246
329
  if (doc) {
@@ -252,11 +335,11 @@ export function initReveal(opts) {
252
335
  //Add plugins
253
336
  finalOptions.plugins = [
254
337
  ...modules,
255
- ...defaultDennisPlugins,
338
+ ...buildDennisPlugins(deps),
339
+ ...esmPlugins,
256
340
  ...finalOptions.plugins,
257
- RevealMermaid,
258
- RevealChalkboard,
259
- RevealCustomControls
341
+ window.RevealChalkboard,
342
+ window.RevealCustomControls
260
343
  ]
261
344
 
262
345
  if (options.verbose)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farberg/reveal-template",
3
- "version": "1.1.19",
3
+ "version": "1.1.21",
4
4
  "homepage": "https://github.com/pfisterer/reveal-template",
5
5
  "description": "Reveal.js template for Dennis' lectures",
6
6
  "main": "index.js",
@@ -18,15 +18,15 @@
18
18
  "@fortawesome/fontawesome-free": "^7.2.0",
19
19
  "asciinema-player": "^3.15.1",
20
20
  "connect": "^3.7.0",
21
- "easyqrcodejs": "^4.6.2",
22
- "file-saver": "^2.0.5",
23
- "jszip": "^3.10.1",
24
- "mermaid": "^11.14.0",
21
+ "fflate": "^0.8.3",
22
+ "mermaid": "^11.15.0",
25
23
  "pdf-merger-js": "^5.1.2",
26
- "puppeteer": "^24.42.0",
24
+ "puppeteer": "^25.0.2",
25
+ "qr-creator": "^1.0.0",
27
26
  "reveal.js": "^6.0.1",
28
27
  "reveal.js-mermaid-plugin": "^11.12.3",
29
28
  "reveal.js-plugins": "^4.6.0",
29
+ "reveal.js-simplemenu": "^2.0.3",
30
30
  "serve-static": "^2.2.1"
31
31
  }
32
32
  }
@@ -1,11 +1,9 @@
1
- function initSlide(slide) {
1
+ function initSlide(asciinemaCreate, slide) {
2
2
  let players = []
3
3
 
4
4
  let asciinemaElements = slide.getElementsByTagName("asciinema")
5
5
 
6
6
  for (let el of asciinemaElements) {
7
- //console.log("Found asciinema element: ", el)
8
-
9
7
  //Make element invisible
10
8
  el.style.display = "none"
11
9
 
@@ -16,8 +14,7 @@ function initSlide(slide) {
16
14
 
17
15
  div.setAttribute('data-farberg-asciinema', 'true')
18
16
 
19
- //console.log("Playing", source, "with options", conf)
20
- players.push(AsciinemaPlayer.create(source, div, JSON.parse(conf)))
17
+ players.push(asciinemaCreate(source, div, JSON.parse(conf)))
21
18
 
22
19
  el.parentNode.insertBefore(div, el.nextSibling)
23
20
  }
@@ -38,7 +35,7 @@ function destroyPlayer(slide, players) {
38
35
  players.forEach(player => player.dispose())
39
36
  }
40
37
 
41
- export default () => {
38
+ export default (asciinemaCreate) => {
42
39
 
43
40
  return {
44
41
  id: 'asciinema',
@@ -46,13 +43,13 @@ export default () => {
46
43
  deck.on('ready', () => {
47
44
  let currentPlayers = undefined
48
45
 
49
- currentPlayers = initSlide(deck.getCurrentSlide())
46
+ currentPlayers = initSlide(asciinemaCreate, deck.getCurrentSlide())
50
47
 
51
48
  deck.addEventListener('slidechanged', function (event) {
52
49
  if (event.previousSlide)
53
50
  destroyPlayer(event.previousSlide, currentPlayers)
54
51
 
55
- currentPlayers = initSlide(event.currentSlide)
52
+ currentPlayers = initSlide(asciinemaCreate, event.currentSlide)
56
53
  })
57
54
  })
58
55
  }
@@ -14,7 +14,7 @@ code/k8s-demo-app/package.json
14
14
  </pre>
15
15
  */
16
16
 
17
- const dir_tree = {
17
+ const dirTreeFactory = ({ zip, strToU8 }) => ({
18
18
  id: 'dir_tree',
19
19
  init: (deck) => {
20
20
 
@@ -244,6 +244,17 @@ const dir_tree = {
244
244
  return tree;
245
245
  }
246
246
 
247
+ function downloadBlob(blob, filename) {
248
+ const url = URL.createObjectURL(blob);
249
+ const a = document.createElement('a');
250
+ a.href = url;
251
+ a.download = filename;
252
+ document.body.appendChild(a);
253
+ a.click();
254
+ document.body.removeChild(a);
255
+ URL.revokeObjectURL(url);
256
+ }
257
+
247
258
  function download(files, zipName) {
248
259
  Promise.all(files.map(f => fetch(f, { credentials: 'include' })))
249
260
  .then(responses => {
@@ -252,9 +263,12 @@ const dir_tree = {
252
263
  return;
253
264
  }
254
265
  return Promise.all(responses.map(r => r.text())).then(values => {
255
- const zip = new JSZip();
256
- values.forEach((text, i) => zip.file(files[i], text));
257
- zip.generateAsync({ type: 'blob' }).then(blob => saveAs(blob, zipName));
266
+ const entries = {};
267
+ values.forEach((text, i) => { entries[files[i]] = strToU8(text); });
268
+ zip(entries, (err, data) => {
269
+ if (err) { console.error('zip failed', err); return; }
270
+ downloadBlob(new Blob([data], { type: 'application/zip' }), zipName);
271
+ });
258
272
  });
259
273
  });
260
274
  }
@@ -378,6 +392,6 @@ const dir_tree = {
378
392
  }
379
393
  });
380
394
  }
381
- }
395
+ })
382
396
 
383
- export default dir_tree;
397
+ export default dirTreeFactory;
@@ -19,20 +19,19 @@
19
19
  */
20
20
 
21
21
 
22
- function showLinkToSlidesAndQrCode(deck, url) {
22
+ function showLinkToSlidesAndQrCode(QrCreator, deck, url) {
23
23
  if (url === undefined)
24
24
  return
25
25
 
26
26
  let qrElements = deck.getSlidesElement().getElementsByClassName('qrcodeforslides')
27
27
  for (let qrel of qrElements) {
28
28
 
29
- new QRCode(qrel, {
29
+ QrCreator.render({
30
30
  text: url,
31
- width: 500,
32
- height: 500,
33
- });
31
+ size: 500,
32
+ }, qrel);
34
33
 
35
- console.log("QR Code for slides generated", qrel, url)
34
+ //console.log("QR Code for slides generated", qrel, url)
36
35
  }
37
36
 
38
37
  let urlElements = deck.getSlidesElement().getElementsByClassName('urlforslides')
@@ -43,7 +42,7 @@ function showLinkToSlidesAndQrCode(deck, url) {
43
42
 
44
43
  }
45
44
 
46
- export default () => {
45
+ export default (QrCreator) => {
47
46
  return {
48
47
  id: 'show_qr_code',
49
48
  init: (deck) => {
@@ -60,7 +59,7 @@ export default () => {
60
59
  return res.json();
61
60
  })
62
61
  .then(json => {
63
- if (json) showLinkToSlidesAndQrCode(deck, json.homepage)
62
+ if (json) showLinkToSlidesAndQrCode(QrCreator, deck, json.homepage)
64
63
  })
65
64
  .catch(err => console.log("Error fetching info json", err))
66
65
  else
@@ -17,6 +17,7 @@ let md_files = fs.readdirSync(".")
17
17
  .filter(file => path.extname(file).toLowerCase() === ".md")
18
18
  .filter(file => !path.basename(file, ".md").startsWith("__"))
19
19
  .filter(file => path.basename(file, ".md") !== "README")
20
+ .filter(file => path.basename(file, ".md") !== "CLAUDE")
20
21
 
21
22
  let generateTable = md_files.map(file => file.match(structuredNameRegexp)).reduce((a, b) => a && b, true)
22
23