Tucker McKnight <tmcknight@instructure.com> | Sun Mar 15 2026
[WIP] broken, hacky attempt to get better diffs. Need to rethink this, just commiting it to remember what I changed. Need to create newlines in one side of the diff if the other side is exclusively adding lines. So maybe change the Diff to check lines instead of words, and then do words (or characters?) per-line once the line diff has been created.
64 65 66 67 68
m('div', {class: "row"}, [
m('div', {class: "col-auto border-end"},
m('pre', {class: "mb-0"}, lineNumbers(hunk.beforeText).map((lineNumber) => {
return (lineNumber + hunk.lineNumber - 1).toString()
}).join('\n'))
),64 65 66 67 68 69
m('div', {class: "row"}, [
m('div', {class: "col-auto border-end"},
m('pre', {class: "mb-0"}, lineNumbers(hunk.beforeText).map((lineNumber) => {
if (lineNumber === null) { return '' }
return (lineNumber + hunk.lineNumber - 1).toString()
}).join('\n'))
),76 77 78 79 80 81
m('span', {class: 'font-monospace text-secondary'}, 'After'),
m('div', {class: "row"},
m('div', {class: "col-auto border-end"},
m('pre', {class: "mb-0"}, lineNumbers(hunk.beforeText).map((lineNumber) => {
return (lineNumber + hunk.lineNumber - 1).toString()
}).join('\n'))
),76 77 78 79 80 81 82
m('span', {class: 'font-monospace text-secondary'}, 'After'),
m('div', {class: "row"},
m('div', {class: "col-auto border-end"},
m('pre', {class: "mb-0"}, lineNumbers(hunk.afterText).map((lineNumber) => {
if (lineNumber === null) { return '' }
return (lineNumber + hunk.lineNumber - 1).toString()
}).join('\n'))
),135 136 137 138 139 140 141 142 143 144
})
eleventyConfig.addFilter("lineNumbers", (code: string) => {
code.split('')
const numLines = code.split('\n').length
const lineNumbers = []
for (let i = 1; i <= numLines; i++) {
lineNumbers.push(i)
}
return lineNumbers135 136 137 138 139 140 141 142 143 144 145 146
})
eleventyConfig.addFilter("lineNumbers", (code: string) => {
const lines = code.split('\n')
console.log(lines)
const numLines = lines.length
const lineNumbers = []
for (let i = 0; i < numLines - 1; i++) {
const lineNum = lines[i].includes('\u{2063}') ? null : i
lineNumbers.push(lineNum)
}
return lineNumbers34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
skipFourStartingAt = -1
}
const lastHunk = lines.slice(previousHunk, hunkEndIndex)
let lastHunkBefore = lastHunk.filter(line => line.startsWith("-")).map(str => str.replace("-", "")).join("\n")
let lastHunkAfter = lastHunk.filter(line => line.startsWith("+")).map(str => str.replace("+", "")).join("\n")
const changeObject = Diff.diffWordsWithSpace(lastHunkBefore, lastHunkAfter)
let beforeText = ""
let afterText = ""
changeObject.forEach((obj) => {
if (!obj.added && !obj.removed) {
beforeText = beforeText + escape(obj.value)
afterText = afterText + escape(obj.value)
}
if (obj.added) {
afterText = afterText + "<mark>" + escape(obj.value) + "</mark>"
}
if (obj.removed) {
beforeText = beforeText + "<mark>" + escape(obj.value) + "</mark>"
}
})
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
skipFourStartingAt = -1
}
const lastHunk = lines.slice(previousHunk, hunkEndIndex)
// TODO: this change I've made doesn't quite work. Need to make it
// skip lines in the other diff when adding lines to just one diff.
lastHunk.forEach((line) => {
if (line.startsWith(' ')) {
line = line.replace(' ', '')
}
else if (line.startsWith('-')) {
line = line.replace('-', '')
}
else if (line.startsWith('+')) {
line = line.replace('+', '')
}
})
let lastHunkBefore = lastHunk.filter((line) => {
return line.startsWith("-") || line.startsWith(" ")
}).map((str) => {
if (str.startsWith('-')) { return str.replace("-", "") }
if (str.startsWith(' ')) { return str.replace(" ", "") }
}).join("\n")
let lastHunkAfter = lastHunk.filter((line) => {
return line.startsWith("+") || line.startsWith(" ")
}).map((str) => {
if (str.startsWith('+')) { return str.replace("+", "") }
if (str.startsWith(' ')) { return str.replace(" ", "") }
}).join("\n")
const changeObject = Diff.diffLines(lastHunkBefore, lastHunkAfter)
let beforeText = ""
let afterText = ""
changeObject.forEach((obj) => {
const numNewLines = obj.value.split('').filter(char => char === '\n').length
if (!obj.added && !obj.removed) {
beforeText = beforeText + escape(obj.value)
afterText = afterText + escape(obj.value)
}
if (obj.added) {
afterText = afterText + "<mark>" + escape(obj.value) + "</mark>"
if (numNewLines > 0) {
beforeText = beforeText + (new Array(numNewLines).fill('\u{2063}', 0).join('\n'))
}
}
if (obj.removed) {
beforeText = beforeText + "<mark>" + escape(obj.value) + "</mark>"
if (numNewLines > 0) {
afterText = afterText + (new Array(numNewLines).fill('\u{2063}', 0).join('\n'))
}
}
})