From 6b22381b1d59e190a76b4461da52a2f9f734de7c Mon Sep 17 00:00:00 2001 From: EmptyWork <22065214+EmptyWork@users.noreply.github.com> Date: Sun, 29 Jun 2025 19:38:50 +0900 Subject: [PATCH 1/4] =?UTF-8?q?create:=20`lib/highlightjs-lines.js`=20?= =?UTF-8?q?=E2=80=94=20hljs-line=20to=20every=20line?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/highlightjs-lines.js | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 lib/highlightjs-lines.js diff --git a/lib/highlightjs-lines.js b/lib/highlightjs-lines.js new file mode 100644 index 0000000..f972dfb --- /dev/null +++ b/lib/highlightjs-lines.js @@ -0,0 +1,43 @@ +/** + * This will convert every lines that is not + * starts with - or + (diff-support) to be encase + * inside a div with the class of hljs-line + * + * @param {*} hljs + * @returns + */ + +export default function (hljs) { + function highlight(code, options) { + const result = hljs.highlight(code, { ...options, language: options.language }) + const lines = result.value.split('\n') + + const processedLines = lines.map(line => { + const hasAddition = line.startsWith(`+`) + const hasDeletion = line.startsWith(`-`) + const isEmpty = line === "" + let outputLine = line.replace("+ ", "+").replace("- ", "-"); + if (!isEmpty && !hasAddition && !hasDeletion) { + outputLine = `${line}` + } + + return outputLine + }).join('\n') + + return { + ...result, + code, + value: processedLines, + language: options.language + } + } + + return { + ...hljs, + highlight(codeOrLanguageName, optionsOrCode, ignoreIllegals = false) { + return typeof optionsOrCode === 'string' + ? highlight(optionsOrCode, { language: codeOrLanguageName, ignoreIllegals }) + : highlight(codeOrLanguageName, optionsOrCode) + } + } +} \ No newline at end of file From c4e983f27ccf865851076852da5650a734f7458e Mon Sep 17 00:00:00 2001 From: EmptyWork <22065214+EmptyWork@users.noreply.github.com> Date: Sun, 29 Jun 2025 19:40:23 +0900 Subject: [PATCH 2/4] =?UTF-8?q?update:=20`.eleventy.js`=20=E2=80=94=20use?= =?UTF-8?q?=20inbuilt=20highlightjs-lines?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eleventy.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eleventy.js b/.eleventy.js index a7ac818..dc10593 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -4,6 +4,7 @@ import dotenv from "dotenv" import { DateTime } from "luxon" import highlight from "highlight.js" import highlightDiff from "highlightjs-code-diff" +import highlightjsLines from "./lib/highlightjs-lines.js" import markdownIt from "markdown-it" import anchor from "markdown-it-anchor" import bracketedSpans from "markdown-it-bracketed-spans" @@ -17,7 +18,7 @@ dotenv.config() export default function (eleventyConfig) { const isDevelopment = process.env.NODE_ENV === "development" - const hljs = highlightDiff(highlight) + const hljs = highlightjsLines(highlightDiff(highlight)) const markdownItConfig = markdownIt({ html: true, linkify: true, From 5859d5291a2ce1e09763f2ee6231054eee155e96 Mon Sep 17 00:00:00 2001 From: EmptyWork <22065214+EmptyWork@users.noreply.github.com> Date: Sun, 29 Jun 2025 19:41:17 +0900 Subject: [PATCH 3/4] =?UTF-8?q?create:=20`lib/highlightjs-lines.test.js`?= =?UTF-8?q?=20=E2=80=94=20unit=20test=20for=20hljs-lines?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/highlightjs-lines.test.js | 122 ++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 lib/highlightjs-lines.test.js diff --git a/lib/highlightjs-lines.test.js b/lib/highlightjs-lines.test.js new file mode 100644 index 0000000..b7793b4 --- /dev/null +++ b/lib/highlightjs-lines.test.js @@ -0,0 +1,122 @@ +import highlight from "highlight.js" +import highlightjsLines from "./highlightjs-lines.js" +import highlightDiff from "highlightjs-code-diff" +import markdownIt from "markdown-it" +import { describe, it } from 'node:test' +import assert from "node:assert" + +const hljsLinesWithDiff = highlightjsLines(highlightDiff(highlight)) +const hljsLines = highlightjsLines(highlight) + +describe('Highlight Lines using Markdown With Diff', () => { + const mIt = markdownIt({ + html: true, + linkify: true, + typographer: true, + highlight: function (str, lang) { + if (lang) { + try { + return hljsLinesWithDiff.highlight(str, { language: lang }).value + } catch (__) { } + } + return "" + } + }) + it('Test With Diff (Deletion)', () => { + const data = ` +\`\`\`diff:js +- setTimeout(() => throw new Error(),0) +\`\`\` +` + const value = mIt.render(data) + assert.strictEqual(value, `
-setTimeout(() => throw new Error(),0)\n
\n`) + }) + it('Test With Diff (Addition)', () => { + const data = ` +\`\`\`diff:js ++ setTimeout(() => throw new Error(),0) +\`\`\` +` + const value = mIt.render(data) + assert.strictEqual(value, `
+setTimeout(() => throw new Error(),0)\n
\n`) + }) + it('Normal Test', () => { + const data = ` +\`\`\`js +let time = new Date() +\`\`\` +` + const value = mIt.render(data) + assert.strictEqual(value, `
let time = new Date()\n
\n`) + }) +}) + +describe("Highlight Lines with Diff", async (t) => { + it("Test With Diff (Deletion)", () => { + const code = ` function helloWorld () { +- return 'Hello' + } +` + const { value } = hljsLinesWithDiff.highlight(code, { language: 'diff:js' }) + assert.strictEqual(value, ` function helloWorld () { +- return 'Hello' + }\n`) + }) + it("Test With Diff (Addition)", () => { + const code = ` function helloWorld () { ++ return 'Hello, world!' + } +` + const { value } = hljsLinesWithDiff.highlight(code, { language: 'diff:js' }) + assert.strictEqual(value, ` function helloWorld () { ++ return 'Hello, world!' + }\n`) + }) + it("Normal Test", () => { + const code = ` function helloWorld () { + return 'Hello' + return 'Hello, world!' + } +` + const { value } = hljsLinesWithDiff.highlight(code, { language: 'diff:js' }) + assert.strictEqual(value, ` function helloWorld () { + return 'Hello' + return 'Hello, world!' + }\n`) + }) +}) + +describe("Highlight Lines", async (t) => { + it("Test With Diff (Deletion)", () => { + const code = ` function helloWorld () { +- return 'Hello' + } +` + const { value } = hljsLines.highlight(code, { language: 'js' }) + assert.strictEqual(value, ` function helloWorld () { +- return 'Hello' + }\n`) + }) + it("Test With Diff (Addition)", () => { + const code = ` function helloWorld () { ++ return 'Hello, world!' + } +` + const { value } = hljsLines.highlight(code, { language: 'js' }) + assert.strictEqual(value, ` function helloWorld () { ++ return 'Hello, world!' + }\n`) + }) + it("Normal Test", () => { + const code = ` function helloWorld () { + return 'Hello' + return 'Hello, world!' + } +` + const { value } = hljsLines.highlight(code, { language: 'js' }) + assert.strictEqual(value, ` function helloWorld () { + return 'Hello' + return 'Hello, world!' + }\n`) + }) +}) \ No newline at end of file From 8ac47250426cf3cd04d9681d7ce9a17972bcff21 Mon Sep 17 00:00:00 2001 From: EmptyWork <22065214+EmptyWork@users.noreply.github.com> Date: Sun, 29 Jun 2025 19:42:58 +0900 Subject: [PATCH 4/4] =?UTF-8?q?update:=20`highlight.scss`=20=E2=80=94=20hl?= =?UTF-8?q?js-line=20styling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/scss/highlight.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/assets/scss/highlight.scss b/src/assets/scss/highlight.scss index b52f6c4..b60866d 100644 --- a/src/assets/scss/highlight.scss +++ b/src/assets/scss/highlight.scss @@ -109,6 +109,7 @@ code.hljs { Additional styling for diff support */ +.hljs-line, .hljs-addition, .hljs-deletion { --_distance: 1em;