From 4e37f53b7adab139315f240912edbebdd4eda229 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Wed, 8 Oct 2025 16:33:14 +0800 Subject: [PATCH] site: show code line numbers conditionally --- site/package-lock.json | 432 ++++++++++++++++++++ site/package.json | 1 + site/src/config.ts | 4 + site/src/routes/docs/[...path]/markdown.css | 2 +- site/src/routes/docs/[...path]/shiki.css | 124 +++--- site/vitePlugins/markdown.ts | 36 +- 6 files changed, 532 insertions(+), 67 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index 7de1fbddb..86a4bbc66 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -15,6 +15,7 @@ "@sveltejs/kit": "^2.43.2", "@sveltejs/vite-plugin-svelte": "^6.2.0", "cssnano": "^7.1.1", + "hast": "^0.0.2", "hast-util-to-html": "^9.0.5", "hastscript": "^9.0.1", "mdast": "^2.3.2", @@ -2794,6 +2795,37 @@ "node": ">=0.10.0" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", @@ -3594,6 +3626,21 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.233", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.233.tgz", @@ -3611,6 +3658,22 @@ "node": ">=0.10.0" } }, + "node_modules/ent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz", + "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "punycode": "^1.4.1", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -3624,6 +3687,39 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.10", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", @@ -3676,6 +3772,13 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, "node_modules/escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", @@ -3946,6 +4049,45 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -4023,6 +4165,19 @@ "node": ">=0.10.0" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4043,6 +4198,35 @@ "node": ">=0.10.0" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -4134,6 +4318,24 @@ "node": ">= 0.4" } }, + "node_modules/hast": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/hast/-/hast-0.0.2.tgz", + "integrity": "sha512-1MrzC9MtAYhzLix2w++pGEtRyCm6N1fcxCjx+1xJo/92fNDRFemFaum18XWd8No3f+FgT9lv6fKOC8LZRcxxuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bail": "^1.0.0", + "camelcase": "^1.2.1", + "ent": "^2.2.0", + "escape-html": "^1.0.3", + "htmlparser2": "^3.8.3", + "param-case": "^1.1.1", + "property-information": "^2.0.0", + "trim": "0.0.1", + "unified": "^2.1.0" + } + }, "node_modules/hast-util-heading-rank": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", @@ -4235,6 +4437,56 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast/node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast/node_modules/camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hast/node_modules/property-information": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-2.0.0.tgz", + "integrity": "sha512-8oVcjnCeqANq/exCzgse3D47GBmgOuI47vNya7xBIJhUXeh49AjZuXWw2gTh1UuN4rfwz5pEv2ZFzu45vBby5A==", + "dev": true, + "license": "MIT" + }, + "node_modules/hast/node_modules/unified": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-2.1.4.tgz", + "integrity": "sha512-qa4nA26ms49OczPueTt7G46r89TOlwAJ4pEk2U4mwkV1wNhjttItF03SE/YnfkgWg14tzmAHXGhJp2GhDYwn1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "attach-ware": "^1.0.0", + "bail": "^1.0.0", + "extend": "^3.0.0", + "unherit": "^1.0.4", + "vfile": "^1.0.0", + "ware": "^1.3.0" + } + }, + "node_modules/hast/node_modules/vfile": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-1.4.0.tgz", + "integrity": "sha512-7Fz639rwERslMqQCuf1/0H4Tqe2q484Xl6X/jsKqrP7IjFcDODFURhv0GekMnImpbj9pTOojtqL7r39LJJkjGA==", + "dev": true, + "license": "MIT" + }, "node_modules/hastscript": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", @@ -4274,6 +4526,105 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/htmlparser2/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/htmlparser2/node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/htmlparser2/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/htmlparser2/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/htmlparser2/node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/htmlparser2/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/htmlparser2/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4566,6 +4917,25 @@ "@types/estree": "^1.0.6" } }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -4691,6 +5061,13 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", + "dev": true, + "license": "MIT" + }, "node_modules/magic-string": { "version": "0.30.19", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", @@ -4731,6 +5108,16 @@ "dev": true, "license": "MIT" }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/math-random": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", @@ -6605,6 +6992,16 @@ "node": ">=0.10.0" } }, + "node_modules/param-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-1.1.2.tgz", + "integrity": "sha512-gksk6zeZQxwBm1AHsKh+XDFsTGf1LvdZSkkpSIkfDtzW+EQj/P2PBgNb3Cs0Y9Xxqmbciv2JZe3fWU6Xbher+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "sentence-case": "^1.1.2" + } + }, "node_modules/parse-entities": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", @@ -8000,6 +8397,13 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, "node_modules/randomatic": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", @@ -8455,6 +8859,24 @@ "ret": "~0.1.10" } }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", @@ -8462,6 +8884,16 @@ "dev": true, "license": "ISC" }, + "node_modules/sentence-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-1.1.3.tgz", + "integrity": "sha512-laa/UDTPXsrQnoN/Kc8ZO7gTeEjMsuPiDgUCk9N0iINRZvqAMCTXjGl8+tD27op1eF/JHbdUlEUmovDh6AX7sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^1.1.1" + } + }, "node_modules/set-cookie-parser": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", diff --git a/site/package.json b/site/package.json index 0cf215922..250c6331e 100644 --- a/site/package.json +++ b/site/package.json @@ -21,6 +21,7 @@ "@sveltejs/kit": "^2.43.2", "@sveltejs/vite-plugin-svelte": "^6.2.0", "cssnano": "^7.1.1", + "hast": "^0.0.2", "hast-util-to-html": "^9.0.5", "hastscript": "^9.0.1", "mdast": "^2.3.2", diff --git a/site/src/config.ts b/site/src/config.ts index 3367109aa..4cae68087 100644 --- a/site/src/config.ts +++ b/site/src/config.ts @@ -25,3 +25,7 @@ export const docs = { }, ] as RawNavLink[], }; + +export const markdown = { + minLineNumberLines: 4, +}; diff --git a/site/src/routes/docs/[...path]/markdown.css b/site/src/routes/docs/[...path]/markdown.css index cb8527350..3ac939325 100644 --- a/site/src/routes/docs/[...path]/markdown.css +++ b/site/src/routes/docs/[...path]/markdown.css @@ -5,6 +5,6 @@ code { font-weight: normal; } -pre code { +pre { overflow: auto; } diff --git a/site/src/routes/docs/[...path]/shiki.css b/site/src/routes/docs/[...path]/shiki.css index c2824e41f..42e1cfa10 100644 --- a/site/src/routes/docs/[...path]/shiki.css +++ b/site/src/routes/docs/[...path]/shiki.css @@ -1,44 +1,43 @@ -@media (prefers-color-scheme: dark) { - .shiki, - .shiki span { - color: var(--shiki-dark) !important; - background-color: var(--shiki-dark-bg) !important; - /* Optional, if you also want font styles */ - font-style: var(--shiki-dark-font-style) !important; - font-weight: var(--shiki-dark-font-weight) !important; - text-decoration: var(--shiki-dark-text-decoration) !important; - } -} - -html.dark .shiki, -html.dark .shiki span { - color: var(--shiki-dark) !important; - background-color: var(--shiki-dark-bg) !important; - /* Optional, if you also want font styles */ - font-style: var(--shiki-dark-font-style) !important; - font-weight: var(--shiki-dark-font-weight) !important; - text-decoration: var(--shiki-dark-text-decoration) !important; -} - .shiki { margin: 0 -15px; padding: 15px; -} -.shiki code { - display: block; -} -.shiki .line { - width: 100%; - display: inline-block; -} -/* line number */ -@media (min-width: 800px) { - .shiki code { + &, + & span { + color: var(--shiki-light); + background-color: var(--shiki-light-bg); + font-style: var(--shiki-light-font-style); + font-weight: var(--shiki-light-font-weight); + text-decoration: var(--shiki-light-text-decoration); + } + + @media (prefers-color-scheme: dark) { + &, + & span, + html.dark &, + html.dark & span { + color: var(--shiki-dark); + background-color: var(--shiki-dark-bg); + font-style: var(--shiki-dark-font-style); + font-weight: var(--shiki-dark-font-weight); + text-decoration: var(--shiki-dark-text-decoration); + } + } + + code { + display: block; + } + .line { + width: 100%; + display: inline-block; + } + + /* line numbers */ + &.line-numbers code { counter-reset: step; counter-increment: step 0; } - .shiki .line::before { + &.line-numbers .line::before { content: counter(step); counter-increment: step; width: 1rem; @@ -47,36 +46,35 @@ html.dark .shiki span { text-align: right; color: rgba(115, 138, 148, 0.4); } -} -/* indent guides */ -.shiki .indent { - display: inline-block; - position: relative; - left: var(--indent-offset); -} + /* indent guides */ + .indent { + display: inline-block; + position: relative; + left: var(--indent-offset); + } + .indent:empty { + height: 1lh; + vertical-align: bottom; + } -.shiki .indent:empty { - height: 1lh; - vertical-align: bottom; -} + .indent::before { + content: ""; + position: absolute; + opacity: 0.15; + width: 1px; + height: 100%; + background-color: currentColor; + } -.shiki .indent::before { - content: ""; - position: absolute; - opacity: 0.15; - width: 1px; - height: 100%; - background-color: currentColor; -} - -/* diff */ -.shiki .line.diff.remove { - background-color: #db0a0a41; -} -.shiki .line.diff.add { - background-color: #0adb4954; -} -.shiki .line.highlighted { - background-color: #00000024; + /* diff */ + .line.diff.remove { + background-color: #db0a0a41; + } + .line.diff.add { + background-color: #0adb4954; + } + .line.highlighted { + background-color: #00000024; + } } diff --git a/site/vitePlugins/markdown.ts b/site/vitePlugins/markdown.ts index a2c9c17a1..5b8a880ef 100644 --- a/site/vitePlugins/markdown.ts +++ b/site/vitePlugins/markdown.ts @@ -13,6 +13,8 @@ import remarkDirective from "remark-directive"; import rehypeAutolinkHeadings from "rehype-autolink-headings"; import { toc } from "mdast-util-toc"; import type { Nodes } from "mdast"; +import type { Element } from "hast"; +import * as config from "../src/config"; import { transformerNotationDiff, transformerNotationHighlight, @@ -38,6 +40,7 @@ export default function (): PluginOption { .use(styleDirectives) .use(remarkRehype) .use(rehypeShiki, { + defaultColor: false, themes: { light: "catppuccin-latte", dark: "catppuccin-macchiato", @@ -49,6 +52,9 @@ export default function (): PluginOption { transformerNotationHighlight(), transformerRenderIndentGuides(), transformerMetaHighlight(), + transformerLineNumbers({ + minLines: config.markdown.minLineNumberLines, + }), ], }) .use(rehypeStringify) @@ -174,11 +180,35 @@ function linkMigration() { return; } // Skip external links, links pointing to /docs already and anchors - if (!node.url || /^(https?:)?\/\/|^\/docs|^#/.test(node.url)) return; + if (!node.url || /^(https?:)?\/\/|^#/.test(node.url)) return; // Remove repeated leading ../ or ./ - const cleanUrl = node.url.replace(/^(\.\.\/|\.\/)+|\.md$/g, ""); - node.url = `/docs/${cleanUrl}`; + const cleanUrl = node.url.replace(/^\.\.?|((\.\.?)\/)+|\.md$/g, ""); + if (!cleanUrl.startsWith("/")) { + throw new Error(`invalid doc link: ${cleanUrl}`); + } + node.url = `${config.docs.base}/${cleanUrl}`; }); }; } + +function transformerLineNumbers({ minLines }: { minLines: number }) { + return { + pre(pre: Element) { + const code = pre.children?.[0] as Element | undefined; + if (!code) { + return; + } + const lines = code.children.reduce((lines, node) => { + if (node.type !== "element" || node.properties.class != "line") { + return lines; + } + return lines + 1; + }, 0); + if (lines < minLines) { + return; + } + pre.properties.class += " line-numbers"; + }, + }; +}