Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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,
Expand Down
43 changes: 43 additions & 0 deletions lib/highlightjs-lines.js
Original file line number Diff line number Diff line change
@@ -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(`<span class="hljs-addition">+`)
const hasDeletion = line.startsWith(`<span class="hljs-deletion">-`)
const isEmpty = line === ""
let outputLine = line.replace("+ ", "<span class='hljs-indicator'>+</span>").replace("- ", "<span class='hljs-indicator'>-</span>");
if (!isEmpty && !hasAddition && !hasDeletion) {
outputLine = `<span class="hljs-line">${line}</span>`
}

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)
}
}
}
122 changes: 122 additions & 0 deletions lib/highlightjs-lines.test.js
Original file line number Diff line number Diff line change
@@ -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, `<pre><code class="language-diff:js"><span class="hljs-deletion"><span class='hljs-indicator'>-</span><span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(),<span class="hljs-number">0</span>)</span>\n</code></pre>\n`)
})
it('Test With Diff (Addition)', () => {
const data = `
\`\`\`diff:js
+ setTimeout(() => throw new Error(),0)
\`\`\`
`
const value = mIt.render(data)
assert.strictEqual(value, `<pre><code class="language-diff:js"><span class="hljs-addition"><span class='hljs-indicator'>+</span><span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(),<span class="hljs-number">0</span>)</span>\n</code></pre>\n`)
})
it('Normal Test', () => {
const data = `
\`\`\`js
let time = new Date()
\`\`\`
`
const value = mIt.render(data)
assert.strictEqual(value, `<pre><code class="language-js"><span class="hljs-line"><span class="hljs-keyword">let</span> time = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>()</span>\n</code></pre>\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, `<span class="hljs-line"> <span class="hljs-keyword">function</span> <span class="hljs-title function_">helloWorld</span> (<span class="hljs-params"></span>) {</span>
<span class="hljs-deletion"><span class='hljs-indicator'>-</span> <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;Hello&#x27;</span></span>
<span class="hljs-line"> }</span>\n`)
})
it("Test With Diff (Addition)", () => {
const code = ` function helloWorld () {
+ return 'Hello, world!'
}
`
const { value } = hljsLinesWithDiff.highlight(code, { language: 'diff:js' })
assert.strictEqual(value, `<span class="hljs-line"> <span class="hljs-keyword">function</span> <span class="hljs-title function_">helloWorld</span> (<span class="hljs-params"></span>) {</span>
<span class="hljs-addition"><span class='hljs-indicator'>+</span> <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;Hello, world!&#x27;</span></span>
<span class="hljs-line"> }</span>\n`)
})
it("Normal Test", () => {
const code = ` function helloWorld () {
return 'Hello'
return 'Hello, world!'
}
`
const { value } = hljsLinesWithDiff.highlight(code, { language: 'diff:js' })
assert.strictEqual(value, `<span class="hljs-line"> <span class="hljs-keyword">function</span> <span class="hljs-title function_">helloWorld</span> (<span class="hljs-params"></span>) {</span>
<span class="hljs-line"> <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;Hello&#x27;</span></span>
<span class="hljs-line"> <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;Hello, world!&#x27;</span></span>
<span class="hljs-line"> }</span>\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, `<span class="hljs-line"> <span class="hljs-keyword">function</span> <span class="hljs-title function_">helloWorld</span> (<span class="hljs-params"></span>) {</span>
<span class="hljs-line">- <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;Hello&#x27;</span></span>
<span class="hljs-line"> }</span>\n`)
})
it("Test With Diff (Addition)", () => {
const code = ` function helloWorld () {
+ return 'Hello, world!'
}
`
const { value } = hljsLines.highlight(code, { language: 'js' })
assert.strictEqual(value, `<span class="hljs-line"> <span class="hljs-keyword">function</span> <span class="hljs-title function_">helloWorld</span> (<span class="hljs-params"></span>) {</span>
<span class="hljs-line">+ <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;Hello, world!&#x27;</span></span>
<span class="hljs-line"> }</span>\n`)
})
it("Normal Test", () => {
const code = ` function helloWorld () {
return 'Hello'
return 'Hello, world!'
}
`
const { value } = hljsLines.highlight(code, { language: 'js' })
assert.strictEqual(value, `<span class="hljs-line"> <span class="hljs-keyword">function</span> <span class="hljs-title function_">helloWorld</span> (<span class="hljs-params"></span>) {</span>
<span class="hljs-line"> <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;Hello&#x27;</span></span>
<span class="hljs-line"> <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;Hello, world!&#x27;</span></span>
<span class="hljs-line"> }</span>\n`)
})
})
1 change: 1 addition & 0 deletions src/assets/scss/highlight.scss
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ code.hljs {
Additional styling for diff support
*/

.hljs-line,
.hljs-addition,
.hljs-deletion {
--_distance: 1em;
Expand Down