diff --git a/cli/build.js b/cli/build.js index b837fb5..d885248 100644 --- a/cli/build.js +++ b/cli/build.js @@ -2,13 +2,13 @@ import { readFileSync, writeFileSync, readdirSync, existsSync, rmSync, mkdirSync import { join, dirname } from 'node:path'; import { glob } from 'glob'; import frontMatter from 'front-matter'; -import hljs from 'highlight.js'; import Handlebars from 'handlebars'; import ejs from 'ejs'; import MarkdownIt from 'markdown-it'; import markdownItTaskLists from 'markdown-it-task-lists'; import markdownItEmoji from 'markdown-it-emoji/light.js'; import markdownItAlerts from '../helpers/markdown-it-alerts.js'; +import { highlightCode } from '../helpers/highlight.js'; import { parse as parseToml } from 'toml'; import '../helpers/index.js'; @@ -16,16 +16,7 @@ const configFile = readFileSync(join(process.cwd(), 'config.toml'), 'utf8'); const config = parseToml(configFile); const md = new MarkdownIt({ - highlight: function (str, lang) { - if (lang && hljs.getLanguage(lang)) { - try { - return '
' +
-               hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
-               '
'; - } catch (__) {} - } - return '
' + md.utils.escapeHtml(str) + '
'; - }, + highlight: highlightCode, html: true }); diff --git a/helpers/highlight.js b/helpers/highlight.js new file mode 100644 index 0000000..cfef2f4 --- /dev/null +++ b/helpers/highlight.js @@ -0,0 +1,18 @@ +import hljs from 'highlight.js'; +import MarkdownIt from 'markdown-it'; + +const mdUtils = MarkdownIt().utils; + +export function highlightCode(str, lang) { + if (lang && hljs.getLanguage(lang)) { + try { + const langLabel = `${mdUtils.escapeHtml(lang)}`; + return langLabel + + `
` +
+             `` +
+             hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
+             '
'; + } catch (__) {} + } + return '
' + mdUtils.escapeHtml(str) + '
'; +} diff --git a/index.js b/index.js index e3100b2..c88c2bb 100644 --- a/index.js +++ b/index.js @@ -3,13 +3,13 @@ import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import { glob } from 'glob'; import frontMatter from 'front-matter'; -import hljs from 'highlight.js'; import express from 'express'; import Handlebars from 'handlebars'; import MarkdownIt from 'markdown-it'; import markdownItTaskLists from 'markdown-it-task-lists'; import markdownItEmoji from 'markdown-it-emoji/light.js'; import markdownItAlerts from './helpers/markdown-it-alerts.js'; +import { highlightCode } from './helpers/highlight.js'; import { parse as parseToml } from 'toml'; import './helpers/index.js'; @@ -24,16 +24,7 @@ const config = parseToml(configFile); // Setup markdown-it const md = new MarkdownIt({ - highlight: function (str, lang) { - if (lang && hljs.getLanguage(lang)) { - try { - return '
' +
-               hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
-               '
'; - } catch (__) {} - } - return '
' + md.utils.escapeHtml(str) + '
'; - }, + highlight: highlightCode, html: true }); diff --git a/public/style.css b/public/style.css index fb53ed7..e20fee8 100644 --- a/public/style.css +++ b/public/style.css @@ -51,6 +51,34 @@ pre.hljs { position: relative; } +pre.hljs code { + display: block; + position: relative; +} + +pre.hljs .code-lang { + position: sticky; + top: 0; + left: 0; + float: left; + background-color: transparent; + color: #888; + padding: 2px 6px; + font-size: 9px; + font-family: 'Courier New', monospace; + font-weight: 600; + line-height: 1; + text-transform: none; + border-top-left-radius: 2px; + border-bottom-right-radius: 3px; + user-select: none; + pointer-events: none; + margin: 0; + margin-bottom: -14px; + display: inline-block; + z-index: 1; +} + .code-wrapper { position: relative; display: inline-block; @@ -264,6 +292,11 @@ blockquote.alert p:last-child { margin-bottom: 0; } +:root.dark .code-lang { + background-color: transparent !important; + color: #666 !important; +} + @media screen and (max-width: 600px) { pre.hljs, .code-wrapper { diff --git a/vercel.json b/vercel.json index 96f4b75..54b3e50 100644 --- a/vercel.json +++ b/vercel.json @@ -2,5 +2,10 @@ "buildCommand": "npm run build", "outputDirectory": "dist", "devCommand": "npm run dev", - "installCommand": "npm install" + "installCommand": "npm install", + "cleanUrls": true, + "trailingSlash": false, + "rewrites": [ + { "source": "/((?!.*\\.).*)", "destination": "/$1.html" } + ] }