@rip-lang/print 0.1.3 → 0.1.5
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/package.json +1 -1
- package/print.rip +77 -15
package/package.json
CHANGED
package/print.rip
CHANGED
|
@@ -200,11 +200,10 @@ def highlightCode(code, lang)
|
|
|
200
200
|
# fall through
|
|
201
201
|
highlighted ?= escapeHtml code
|
|
202
202
|
|
|
203
|
-
# Add line numbers
|
|
203
|
+
# Add line numbers (fixed 4-digit width for consistent gutter)
|
|
204
204
|
lines = highlighted.split('\n')
|
|
205
|
-
width = String(lines.length).length
|
|
206
205
|
numbered = lines.map (line, i) ->
|
|
207
|
-
num = String(i + 1).padStart(
|
|
206
|
+
num = String(i + 1).padStart(4)
|
|
208
207
|
"<span class=\"line-num\">#{num}</span> #{line}"
|
|
209
208
|
numbered.join('\n')
|
|
210
209
|
|
|
@@ -274,11 +273,40 @@ for section, i in sections
|
|
|
274
273
|
|
|
275
274
|
"""
|
|
276
275
|
|
|
277
|
-
#
|
|
278
|
-
hljsTheme = if dark then 'github-dark' else 'github'
|
|
276
|
+
# Load highlight.js theme CSS files
|
|
279
277
|
hljsMain = import.meta.resolve 'highlight.js'
|
|
280
278
|
hljsDir = join hljsMain.replace('file://', '').replace(/\/[^/]+$/, ''), '..', 'styles'
|
|
281
|
-
|
|
279
|
+
|
|
280
|
+
themes = [
|
|
281
|
+
{ id: 'github', name: 'GitHub Light', dark: false }
|
|
282
|
+
{ id: 'atom-one-light', name: 'Atom One Light', dark: false }
|
|
283
|
+
{ id: 'vs', name: 'Visual Studio', dark: false }
|
|
284
|
+
{ id: 'xcode', name: 'Xcode', dark: false }
|
|
285
|
+
{ id: 'intellij-light', name: 'IntelliJ Light', dark: false }
|
|
286
|
+
{ id: 'stackoverflow-light', name: 'Stack Overflow', dark: false }
|
|
287
|
+
{ id: 'default', name: 'Default Light', dark: false }
|
|
288
|
+
{ id: 'github-dark', name: 'GitHub Dark', dark: true }
|
|
289
|
+
{ id: 'atom-one-dark', name: 'Atom One Dark', dark: true }
|
|
290
|
+
{ id: 'monokai', name: 'Monokai', dark: true }
|
|
291
|
+
{ id: 'nord', name: 'Nord', dark: true }
|
|
292
|
+
{ id: 'vs2015', name: 'VS 2015 Dark', dark: true }
|
|
293
|
+
{ id: 'tokyo-night-dark', name: 'Tokyo Night', dark: true }
|
|
294
|
+
{ id: 'night-owl', name: 'Night Owl', dark: true }
|
|
295
|
+
]
|
|
296
|
+
|
|
297
|
+
defaultTheme = if dark then 'github-dark' else 'github'
|
|
298
|
+
|
|
299
|
+
# Load all theme CSS into a JS object for runtime switching
|
|
300
|
+
defaultCss = readFileSync join(hljsDir, "#{defaultTheme}.css"), 'utf-8'
|
|
301
|
+
themeEntries = []
|
|
302
|
+
themeOptions = ''
|
|
303
|
+
for theme in themes
|
|
304
|
+
css = readFileSync join(hljsDir, "#{theme.id}.css"), 'utf-8'
|
|
305
|
+
encoded = Buffer.from(css).toString('base64')
|
|
306
|
+
themeEntries.push "'#{theme.id}':{d:#{theme.dark},c:atob('#{encoded}')}"
|
|
307
|
+
selected = if theme.id is defaultTheme then ' selected' else ''
|
|
308
|
+
themeOptions += "<option value=\"#{theme.id}\" data-dark=\"#{theme.dark}\"#{selected}>#{theme.name}</option>\n"
|
|
309
|
+
themeData = themeEntries.join(",\n ")
|
|
282
310
|
|
|
283
311
|
html = """
|
|
284
312
|
<!DOCTYPE html>
|
|
@@ -287,11 +315,14 @@ html = """
|
|
|
287
315
|
<meta charset="utf-8">
|
|
288
316
|
<title>rip-print</title>
|
|
289
317
|
<link rel="icon" href="data:,">
|
|
290
|
-
<style>#{
|
|
318
|
+
<style id="hljs-theme">#{defaultCss}</style>
|
|
291
319
|
<style>
|
|
292
320
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
293
321
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #{bgColor}; color: #{textColor}; }
|
|
294
322
|
|
|
323
|
+
.toolbar { padding: 8px 16px; border-bottom: 1px solid #{borderColor}; text-align: right; font-size: 13px; }
|
|
324
|
+
.toolbar select { font-size: 13px; padding: 4px 8px; border-radius: 3px; border: 1px solid #{borderColor}; background: #{bgColor}; color: #{textColor}; }
|
|
325
|
+
.toolbar label { color: #888; margin-left: 16px; }
|
|
295
326
|
.toc { padding: 20px 30px; border-bottom: 1px solid #{borderColor}; }
|
|
296
327
|
.toc h2 { font-size: 18px; margin-bottom: 10px; }
|
|
297
328
|
.toc ol { padding-left: 24px; columns: 2; column-gap: 40px; }
|
|
@@ -300,17 +331,17 @@ html = """
|
|
|
300
331
|
.toc a:hover { text-decoration: underline; }
|
|
301
332
|
.meta { color: #888; font-size: 12px; }
|
|
302
333
|
|
|
303
|
-
.file-section { margin-bottom: 0; }
|
|
334
|
+
.file-section { margin-bottom: 0; margin-top: -1px; }
|
|
304
335
|
.file-header {
|
|
305
|
-
background: #{headerBg}; padding:
|
|
306
|
-
border-top: 1px solid #{borderColor}; border-bottom: 1px solid #{borderColor};
|
|
336
|
+
background: #{headerBg}; padding: 10px 16px 10px 5.85em; font-size: 13px; font-weight: 600;
|
|
337
|
+
border-top: 1px solid #{borderColor}; border-bottom: 1px solid #{borderColor};
|
|
307
338
|
display: flex; justify-content: space-between; align-items: center;
|
|
308
339
|
}
|
|
309
340
|
.nav { font-weight: normal; font-size: 12px; }
|
|
310
|
-
.nav a { color: #888; text-decoration: none;
|
|
311
|
-
.nav a:hover { color: #{textColor}; }
|
|
341
|
+
.nav a { color: #888; text-decoration: none; padding: 6px 10px; border-radius: 3px; }
|
|
342
|
+
.nav a:hover { color: #{textColor}; background: #{if dark then '#30363d' else '#e0e0e0'}; }
|
|
312
343
|
|
|
313
|
-
.code-container { overflow-x: auto; }
|
|
344
|
+
.code-container { overflow-x: auto; border-bottom: 1px solid #{borderColor}; }
|
|
314
345
|
.code-container pre { margin: 0; border-radius: 0; }
|
|
315
346
|
.code-container code { font-size: 13px; line-height: 1.5; padding: 0 !important; display: block; }
|
|
316
347
|
.line-num { color: #aaa; background: #{if dark then '#161b22' else '#f4f4f4'}; user-select: none; display: inline-block; min-width: 2em; text-align: right; padding: 0 0.7em; margin-right: 0.7em; border-right: 1px solid #{borderColor}; }
|
|
@@ -318,18 +349,49 @@ html = """
|
|
|
318
349
|
@media print {
|
|
319
350
|
.toc { page-break-after: always; }
|
|
320
351
|
.file-header { background: #f0f0f0 !important; color: #000 !important; }
|
|
352
|
+
.toolbar { display: none; }
|
|
321
353
|
.nav { display: none; }
|
|
322
|
-
.file-section { page-break-before: always; }
|
|
323
|
-
.file-section:first-of-type { page-break-before: avoid; }
|
|
324
354
|
body { background: white !important; color: black !important; }
|
|
325
355
|
code { font-size: 11px !important; }
|
|
326
356
|
}
|
|
327
357
|
</style>
|
|
328
358
|
</head>
|
|
329
359
|
<body>
|
|
360
|
+
<div class="toolbar">
|
|
361
|
+
<label>Theme: <select id="theme-picker">
|
|
362
|
+
<optgroup label="Light">#{themeOptions.split('\n').filter((o) -> o.includes('data-dark="false"')).join('')}</optgroup>
|
|
363
|
+
<optgroup label="Dark">#{themeOptions.split('\n').filter((o) -> o.includes('data-dark="true"')).join('')}</optgroup>
|
|
364
|
+
</select></label>
|
|
365
|
+
</div>
|
|
330
366
|
<a name="top"></a>
|
|
331
367
|
#{toc}
|
|
332
368
|
#{fileSections}
|
|
369
|
+
<script>
|
|
370
|
+
var themes = {
|
|
371
|
+
#{themeData}
|
|
372
|
+
};
|
|
373
|
+
document.getElementById('theme-picker').addEventListener('change', function(e) {
|
|
374
|
+
var id = e.target.value;
|
|
375
|
+
var t = themes[id];
|
|
376
|
+
if (!t) return;
|
|
377
|
+
document.getElementById('hljs-theme').textContent = t.c;
|
|
378
|
+
var d = t.d;
|
|
379
|
+
var bg = d ? '#0d1117' : '#ffffff';
|
|
380
|
+
var fg = d ? '#e6edf3' : '#1f2328';
|
|
381
|
+
var hdr = d ? '#161b22' : '#f6f8fa';
|
|
382
|
+
var brd = d ? '#30363d' : '#d0d7de';
|
|
383
|
+
var gut = d ? '#161b22' : '#f4f4f4';
|
|
384
|
+
document.body.style.background = bg;
|
|
385
|
+
document.body.style.color = fg;
|
|
386
|
+
document.querySelectorAll('.toolbar').forEach(function(e) { e.style.borderColor = brd; });
|
|
387
|
+
document.querySelectorAll('.toolbar select').forEach(function(e) { e.style.background = bg; e.style.color = fg; e.style.borderColor = brd; });
|
|
388
|
+
document.querySelectorAll('.toc').forEach(function(e) { e.style.borderColor = brd; });
|
|
389
|
+
document.querySelectorAll('.file-header').forEach(function(e) { e.style.background = hdr; e.style.borderColor = brd; e.style.color = fg; });
|
|
390
|
+
document.querySelectorAll('.line-num').forEach(function(e) { e.style.background = gut; e.style.borderColor = brd; });
|
|
391
|
+
document.querySelectorAll('.code-container').forEach(function(e) { e.style.borderColor = brd; });
|
|
392
|
+
document.querySelectorAll('.toc a').forEach(function(e) { e.style.color = fg; });
|
|
393
|
+
});
|
|
394
|
+
</script>
|
|
333
395
|
</body>
|
|
334
396
|
</html>
|
|
335
397
|
"""
|