markserv 1.17.4 → 1.19.1

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.
@@ -1 +1,243 @@
1
- .hljs{display:block;background:white;padding:0.5em;color:#333333;overflow-x:auto}.hljs-comment,.hljs-meta{color:#969896}.hljs-string,.hljs-variable,.hljs-template-variable,.hljs-strong,.hljs-emphasis,.hljs-quote{color:#df5000}.hljs-keyword,.hljs-selector-tag,.hljs-type{color:#a71d5d}.hljs-literal,.hljs-symbol,.hljs-bullet,.hljs-attribute{color:#0086b3}.hljs-section,.hljs-name{color:#63a35c}.hljs-tag{color:#333333}.hljs-title,.hljs-attr,.hljs-selector-id,.hljs-selector-class,.hljs-selector-attr,.hljs-selector-pseudo{color:#795da3}.hljs-addition{color:#55a532;background-color:#eaffea}.hljs-deletion{color:#bd2c00;background-color:#ffecec}.hljs-link{text-decoration:underline}
1
+ /* highlight.js — theme-aware syntax highlighting */
2
+
3
+ .hljs {
4
+ display: block;
5
+ padding: 0.5em;
6
+ overflow-x: auto;
7
+ }
8
+
9
+ /* Light theme (original github-gist) */
10
+ [data-theme="light"] .hljs {
11
+ background: white;
12
+ color: #333333;
13
+ }
14
+ [data-theme="light"] .hljs-comment,
15
+ [data-theme="light"] .hljs-meta {
16
+ color: #969896;
17
+ }
18
+ [data-theme="light"] .hljs-string,
19
+ [data-theme="light"] .hljs-variable,
20
+ [data-theme="light"] .hljs-template-variable,
21
+ [data-theme="light"] .hljs-strong,
22
+ [data-theme="light"] .hljs-emphasis,
23
+ [data-theme="light"] .hljs-quote {
24
+ color: #df5000;
25
+ }
26
+ [data-theme="light"] .hljs-keyword,
27
+ [data-theme="light"] .hljs-selector-tag,
28
+ [data-theme="light"] .hljs-type {
29
+ color: #a71d5d;
30
+ }
31
+ [data-theme="light"] .hljs-literal,
32
+ [data-theme="light"] .hljs-symbol,
33
+ [data-theme="light"] .hljs-bullet,
34
+ [data-theme="light"] .hljs-attribute {
35
+ color: #0086b3;
36
+ }
37
+ [data-theme="light"] .hljs-section,
38
+ [data-theme="light"] .hljs-name {
39
+ color: #63a35c;
40
+ }
41
+ [data-theme="light"] .hljs-tag {
42
+ color: #333333;
43
+ }
44
+ [data-theme="light"] .hljs-title,
45
+ [data-theme="light"] .hljs-attr,
46
+ [data-theme="light"] .hljs-selector-id,
47
+ [data-theme="light"] .hljs-selector-class,
48
+ [data-theme="light"] .hljs-selector-attr,
49
+ [data-theme="light"] .hljs-selector-pseudo {
50
+ color: #795da3;
51
+ }
52
+ [data-theme="light"] .hljs-addition {
53
+ color: #55a532;
54
+ background-color: #eaffea;
55
+ }
56
+ [data-theme="light"] .hljs-deletion {
57
+ color: #bd2c00;
58
+ background-color: #ffecec;
59
+ }
60
+ [data-theme="light"] .hljs-link {
61
+ text-decoration: underline;
62
+ }
63
+
64
+ /* Dark theme (GitHub dark) */
65
+ [data-theme="dark"] .hljs {
66
+ background: #161b22;
67
+ color: #e6edf3;
68
+ }
69
+ [data-theme="dark"] .hljs-comment,
70
+ [data-theme="dark"] .hljs-meta {
71
+ color: #8b949e;
72
+ }
73
+ [data-theme="dark"] .hljs-string,
74
+ [data-theme="dark"] .hljs-variable,
75
+ [data-theme="dark"] .hljs-template-variable,
76
+ [data-theme="dark"] .hljs-strong,
77
+ [data-theme="dark"] .hljs-emphasis,
78
+ [data-theme="dark"] .hljs-quote {
79
+ color: #a5d6ff;
80
+ }
81
+ [data-theme="dark"] .hljs-keyword,
82
+ [data-theme="dark"] .hljs-selector-tag,
83
+ [data-theme="dark"] .hljs-type {
84
+ color: #ff7b72;
85
+ }
86
+ [data-theme="dark"] .hljs-literal,
87
+ [data-theme="dark"] .hljs-symbol,
88
+ [data-theme="dark"] .hljs-bullet,
89
+ [data-theme="dark"] .hljs-attribute {
90
+ color: #79c0ff;
91
+ }
92
+ [data-theme="dark"] .hljs-section,
93
+ [data-theme="dark"] .hljs-name {
94
+ color: #7ee787;
95
+ }
96
+ [data-theme="dark"] .hljs-tag {
97
+ color: #e6edf3;
98
+ }
99
+ [data-theme="dark"] .hljs-title,
100
+ [data-theme="dark"] .hljs-attr,
101
+ [data-theme="dark"] .hljs-selector-id,
102
+ [data-theme="dark"] .hljs-selector-class,
103
+ [data-theme="dark"] .hljs-selector-attr,
104
+ [data-theme="dark"] .hljs-selector-pseudo {
105
+ color: #d2a8ff;
106
+ }
107
+ [data-theme="dark"] .hljs-addition {
108
+ color: #aff5b4;
109
+ background-color: #033a16;
110
+ }
111
+ [data-theme="dark"] .hljs-deletion {
112
+ color: #ffdcd7;
113
+ background-color: #67060c;
114
+ }
115
+ [data-theme="dark"] .hljs-link {
116
+ text-decoration: underline;
117
+ }
118
+
119
+ /* Synthwave theme */
120
+ [data-theme="synthwave"] .hljs {
121
+ background: #1a1228;
122
+ color: #e0d0ff;
123
+ }
124
+ [data-theme="synthwave"] .hljs-comment,
125
+ [data-theme="synthwave"] .hljs-meta {
126
+ color: #6c5987;
127
+ font-style: italic;
128
+ }
129
+ [data-theme="synthwave"] .hljs-string,
130
+ [data-theme="synthwave"] .hljs-variable,
131
+ [data-theme="synthwave"] .hljs-template-variable,
132
+ [data-theme="synthwave"] .hljs-strong,
133
+ [data-theme="synthwave"] .hljs-emphasis,
134
+ [data-theme="synthwave"] .hljs-quote {
135
+ color: #ff8b39;
136
+ }
137
+ [data-theme="synthwave"] .hljs-keyword,
138
+ [data-theme="synthwave"] .hljs-selector-tag,
139
+ [data-theme="synthwave"] .hljs-type {
140
+ color: #ff7edb;
141
+ }
142
+ [data-theme="synthwave"] .hljs-literal,
143
+ [data-theme="synthwave"] .hljs-symbol,
144
+ [data-theme="synthwave"] .hljs-bullet,
145
+ [data-theme="synthwave"] .hljs-attribute {
146
+ color: #36f9f6;
147
+ }
148
+ [data-theme="synthwave"] .hljs-section,
149
+ [data-theme="synthwave"] .hljs-name {
150
+ color: #72f1b8;
151
+ }
152
+ [data-theme="synthwave"] .hljs-tag {
153
+ color: #e0d0ff;
154
+ }
155
+ [data-theme="synthwave"] .hljs-title,
156
+ [data-theme="synthwave"] .hljs-attr,
157
+ [data-theme="synthwave"] .hljs-selector-id,
158
+ [data-theme="synthwave"] .hljs-selector-class,
159
+ [data-theme="synthwave"] .hljs-selector-attr,
160
+ [data-theme="synthwave"] .hljs-selector-pseudo {
161
+ color: #fede5d;
162
+ }
163
+ [data-theme="synthwave"] .hljs-addition {
164
+ color: #72f1b8;
165
+ background-color: #1a3a2a;
166
+ }
167
+ [data-theme="synthwave"] .hljs-deletion {
168
+ color: #ff7edb;
169
+ background-color: #3a1a2a;
170
+ }
171
+ [data-theme="synthwave"] .hljs-link {
172
+ text-decoration: underline;
173
+ color: #36f9f6;
174
+ }
175
+
176
+ /* Solarized theme — Hopscotch syntax highlighting (github.com/idleberg/Hopscotch) */
177
+ [data-theme="solarized"] .hljs {
178
+ background: #322931;
179
+ color: #b9b5b8;
180
+ }
181
+ [data-theme="solarized"] .hljs-comment,
182
+ [data-theme="solarized"] .hljs-meta {
183
+ color: #797379;
184
+ font-style: italic;
185
+ }
186
+ [data-theme="solarized"] .hljs-string,
187
+ [data-theme="solarized"] .hljs-variable,
188
+ [data-theme="solarized"] .hljs-template-variable,
189
+ [data-theme="solarized"] .hljs-strong,
190
+ [data-theme="solarized"] .hljs-emphasis,
191
+ [data-theme="solarized"] .hljs-quote {
192
+ color: #8fc13e;
193
+ }
194
+ [data-theme="solarized"] .hljs-keyword,
195
+ [data-theme="solarized"] .hljs-selector-tag,
196
+ [data-theme="solarized"] .hljs-type {
197
+ color: #c85e7c;
198
+ }
199
+ [data-theme="solarized"] .hljs-literal,
200
+ [data-theme="solarized"] .hljs-symbol,
201
+ [data-theme="solarized"] .hljs-bullet,
202
+ [data-theme="solarized"] .hljs-attribute {
203
+ color: #fd8b19;
204
+ }
205
+ [data-theme="solarized"] .hljs-section,
206
+ [data-theme="solarized"] .hljs-name {
207
+ color: #dd464c;
208
+ }
209
+ [data-theme="solarized"] .hljs-tag {
210
+ color: #b9b5b8;
211
+ }
212
+ [data-theme="solarized"] .hljs-title,
213
+ [data-theme="solarized"] .hljs-attr,
214
+ [data-theme="solarized"] .hljs-selector-id,
215
+ [data-theme="solarized"] .hljs-selector-class,
216
+ [data-theme="solarized"] .hljs-selector-attr,
217
+ [data-theme="solarized"] .hljs-selector-pseudo {
218
+ color: #1290bf;
219
+ }
220
+ [data-theme="solarized"] .hljs-addition {
221
+ color: #8fc13e;
222
+ background-color: rgba(143, 193, 62, 0.1);
223
+ }
224
+ [data-theme="solarized"] .hljs-deletion {
225
+ color: #dd464c;
226
+ background-color: rgba(221, 70, 76, 0.1);
227
+ }
228
+ [data-theme="solarized"] .hljs-link {
229
+ text-decoration: underline;
230
+ color: #1290bf;
231
+ }
232
+ [data-theme="solarized"] .hljs-number {
233
+ color: #fd8b19;
234
+ }
235
+ [data-theme="solarized"] .hljs-built_in {
236
+ color: #fd8b19;
237
+ }
238
+ [data-theme="solarized"] .hljs-params {
239
+ color: #b9b5b8;
240
+ }
241
+ [data-theme="solarized"] .hljs-regexp {
242
+ color: #dd464c;
243
+ }
@@ -1,11 +1,15 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html data-theme="{{theme}}">
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
7
  <title>{{title}}</title>
8
8
  <meta charset="utf-8">
9
+ <link rel="stylesheet" id="theme-dark" href="{markserv}templates/github-markdown-dark.css"{{#unless themeDark}} disabled{{/unless}}>
10
+ <link rel="stylesheet" id="theme-light" href="{markserv}templates/github-markdown-light.css"{{#unless themeLight}} disabled{{/unless}}>
11
+ <link rel="stylesheet" id="theme-synthwave" href="{markserv}templates/github-markdown-synthwave.css"{{#unless themeSynthwave}} disabled{{/unless}}>
12
+ <link rel="stylesheet" id="theme-solarized" href="{markserv}templates/github-markdown-solarized.css"{{#unless themeSolarized}} disabled{{/unless}}>
9
13
  <link rel="stylesheet" href="{markserv}templates/markserv.css">
10
14
  <link rel="stylesheet" href="{markserv}templates/highlight-js-github-gist.css">
11
15
  <script type="text/javascript" id="MathJax-script" async
@@ -17,5 +21,157 @@
17
21
  {{{content}}}
18
22
  <footer><sup><hr> Served by <a href="https://www.npmjs.com/package/markserv">MarkServ</a> | PID: {{pid}}</sup></footer>
19
23
  </article>
24
+ <div class="width-control" id="width-control">
25
+ <span id="width-tooltip"></span>
26
+ <input type="range" id="width-slider" min="0" max="1920" value="978" step="1">
27
+ </div>
28
+ <button class="theme-toggle" id="theme-toggle" title="Toggle theme"></button>
29
+ <script>
30
+ (function() {
31
+ var themes = ['dark', 'light', 'synthwave', 'solarized'];
32
+ var icons = {dark: '\u{1F319}', light: '\u{2600}\u{FE0F}', synthwave: '\u{1F9D1}\u{200D}\u{1F3A4}', solarized: '\u{262F}\u{FE0F}'};
33
+ var serverTheme = '{{theme}}' || 'dark';
34
+ var current = localStorage.getItem('markserv-theme') || serverTheme;
35
+
36
+ function applyTheme(t) {
37
+ document.documentElement.setAttribute('data-theme', t);
38
+ themes.forEach(function(name) {
39
+ var el = document.getElementById('theme-' + name);
40
+ if (el) el.disabled = (name !== t);
41
+ });
42
+ var btn = document.getElementById('theme-toggle');
43
+ if (btn) btn.textContent = icons[t] || icons.dark;
44
+ current = t;
45
+ }
46
+
47
+ applyTheme(current);
48
+
49
+ document.getElementById('theme-toggle').addEventListener('click', function() {
50
+ var idx = themes.indexOf(current);
51
+ var next = themes[(idx + 1) % themes.length];
52
+ localStorage.setItem('markserv-theme', next);
53
+ applyTheme(next);
54
+ });
55
+ })();
56
+ </script>
57
+ <script>
58
+ (function() {
59
+ var slider = document.getElementById('width-slider');
60
+ var tooltip = document.getElementById('width-tooltip');
61
+ if (!slider) return;
62
+
63
+ var CSS_DEFAULT = 978; // must match body { width } in markserv.css
64
+ var storageKey = 'markserv-width:' + '{{rootDir}}';
65
+ var stored = localStorage.getItem(storageKey);
66
+
67
+ function updateSliderMax() {
68
+ // Slider max = current viewport width so user can slide up to full-bleed
69
+ slider.max = window.innerWidth;
70
+ }
71
+
72
+ function applyWidth(px) {
73
+ if (px === CSS_DEFAULT) {
74
+ // Matches stylesheet default — remove inline style so CSS rules apply normally
75
+ document.body.style.width = '';
76
+ } else {
77
+ document.body.style.width = px + 'px';
78
+ }
79
+ slider.value = Math.min(px, parseInt(slider.max, 10));
80
+ }
81
+
82
+ // Initialize
83
+ updateSliderMax();
84
+ if (stored) {
85
+ applyWidth(parseInt(stored, 10));
86
+ } else {
87
+ // No stored value — keep the 978px stylesheet default; slider reflects it
88
+ slider.value = Math.min(CSS_DEFAULT, parseInt(slider.max, 10));
89
+ }
90
+
91
+ function positionTooltip() {
92
+ if (!tooltip) return;
93
+ var val = parseInt(slider.value, 10);
94
+ var min = parseInt(slider.min, 10);
95
+ var max = parseInt(slider.max, 10);
96
+ var pct = (val - min) / (max - min);
97
+ var sliderW = slider.offsetWidth;
98
+ var thumbW = 14;
99
+ var offset = thumbW / 2 + pct * (sliderW - thumbW);
100
+ tooltip.textContent = val + 'px';
101
+ tooltip.style.left = offset + 'px';
102
+ tooltip.style.transform = 'translateX(-50%)';
103
+ }
104
+
105
+ // Slider input → live update
106
+ slider.addEventListener('input', function() {
107
+ var val = parseInt(slider.value, 10);
108
+ applyWidth(val);
109
+ localStorage.setItem(storageKey, String(val));
110
+ if (tooltip) tooltip.classList.add('visible');
111
+ positionTooltip();
112
+ });
113
+
114
+ slider.addEventListener('mousedown', function() {
115
+ if (tooltip) tooltip.classList.add('visible');
116
+ positionTooltip();
117
+ });
118
+
119
+ window.addEventListener('mouseup', function() {
120
+ if (tooltip) tooltip.classList.remove('visible');
121
+ });
122
+
123
+ slider.addEventListener('focus', function() {
124
+ if (tooltip) tooltip.classList.add('visible');
125
+ positionTooltip();
126
+ });
127
+
128
+ slider.addEventListener('blur', function() {
129
+ if (tooltip) tooltip.classList.remove('visible');
130
+ });
131
+
132
+ // Double-click to reset to default width
133
+ slider.addEventListener('dblclick', function() {
134
+ applyWidth(CSS_DEFAULT);
135
+ localStorage.removeItem(storageKey);
136
+ });
137
+
138
+ // On window resize, update slider max to reflect new viewport
139
+ window.addEventListener('resize', function() {
140
+ updateSliderMax();
141
+ });
142
+ })();
143
+ </script>
144
+ {{#if hotreload}}
145
+ <script>
146
+ (function() {
147
+ var ws;
148
+ var delay = 1000;
149
+ var maxDelay = 30000;
150
+ var maxRetries = 20;
151
+ var retries = 0;
152
+
153
+ function connect() {
154
+ ws = new WebSocket('ws://localhost:{{wsPort}}');
155
+ ws.onopen = function() {
156
+ delay = 1000;
157
+ retries = 0;
158
+ ws.send(JSON.stringify({path: location.pathname}));
159
+ };
160
+ ws.onmessage = function(e) {
161
+ var el = document.querySelector('.markdown-body');
162
+ if (el) el.innerHTML = e.data;
163
+ };
164
+ ws.onclose = function() {
165
+ if (retries < maxRetries) {
166
+ retries++;
167
+ setTimeout(connect, delay);
168
+ delay = Math.min(delay * 2, maxDelay);
169
+ }
170
+ };
171
+ }
172
+ connect();
173
+ })();
174
+ </script>
175
+ {{/if}}
20
176
  </body>
21
177
  </html>