Mon Mar 24 2025
tucker.mcknight@gmail.com
0469c81b2235a7a203dd3987593ad50d7560c1fe
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/lightfair.min.css" integrity="sha512-7XR4V1+vHjARBIMw1snyPoLn7d9U9gjBUhGAXVMRXRvXpfyjfmHiAnwxc9eP4imeh0gr7cBvDg9XO06OBj3+jA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/css.min.js" integrity="sha512-fQhadp2Av4sRhTYd9TEggQW4NrosThwDUXIMLin90uepvmCZG0mRTdPVtHujrXD22qMTtdQlrAEdvWocezI8ow==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/javascript.min.js" integrity="sha512-yfJUrNGEC39mHLjZ37CZG69Ij9Vnan7NHxXVuuBxafgfk4F+n7j/NhNWtyhKGTYEgWfgUqzPYMZJZY1HIsPCbQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/vbscript-html.min.js" integrity="sha512-mUJi3ZwVpRAfHxxDIUZO6te8tOtuyIsmkmHaqNOAFuWXPVLmuYNMqamnfCtkNAw8JMGU13K2U/kBYAo+oyKA7Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/es/languages/haskell.min.js" integrity="sha512-LCK3W51vjLBoiaWiFjJq4jBFOuRqx1i6h/Ta6PxzWRyLg+/eCIGDFtuE4hDPBGq3gDvWs7fJUyKfVQ1UMTPBrg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/makefile.min.js" integrity="sha512-lLnMPGLNcEgvwt6f291Bp+WqF3HRxv+8q1t6PA/XTwZH/D1XLB2tUayRAjfAp6AAUrrieJnXQCUtGZtcMhP6ag==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
hljs.addPlugin({
'after:highlightElement': ({ el, result, text }) => {
console.log(text)
const diffType = el.attributes['data-type'].value
const index = parseInt(el.attributes['data-hunk-index'].value)
let diffRanges = null
if (diffType === "before") {
diffRanges = previousDiffMarkers[index]
}
else {
diffRanges = afterDiffMarkers[index]
}
diffRanges.forEach((diffRange) => {
let conceptualCharacter = 0
let inATag = false
for (let i = 0; i < result.value.length; i++) {
// Chomp along until we find diffRange[0]. Increment "conceptualCharacter"
// when we are in a part of the string that is *not* part of an HTML tag that
// highlightjs added. Keep going until conceptualCharacter == diffRange[0].
if (result.value[i] === "<") {
inATag = true
continue
}
if (result.value[i] === ">") {
inATag = false
continue
}
conceptualCharacter++
}
})
}
});
hljs.highlightAll({cssSelector: "pre.hljs code"});
</script>
eleventyConfig.addFilter("jsonStringify", data => JSON.stringify(data))
<code ><pre>
<pre class="code hljs"><code>
</pre></code>
</code></pre>
let previousText = ""
const previousDiffMarkers = []
let gapToNextPreviousDiff = 0
let afterText = ""
const afterDiffMarkers = []
let gapToNextAfterDiff = 0
// TODO: don't actually save lastHunkBefore and lastHunkAfter. Instead,
// recreate them from the change objects. Add to lastHunkBefore if `removed` is true,
// add to lastHunkAfter if `added` is true, add to both if both `removed` and `added`
// are *false*.
// While doing so, keep track of the character count at each added/removed point.
// We'll need that to make a highlightjs plugin that highlights those portions
// after the lighlighting has been applied.
// Maybe add an array of tuples to the hunks object, with each typing being the
// starting-character and ending-charcter (indices) of when to highlight in red
// or green.
// Also keep in mind that some characters will turn into multiple characters
// after highlightjs has done its thing. (& becomes & for example.)
// It's these: https://stackoverflow.com/questions/7381974/which-characters-need-to-be-escaped-in-html
if (!obj.added && !obj.removed) {
previousText = previousText + obj.value
afterText = afterText + obj.value
gapToNextPreviousDiff = gapToNextPreviousDiff + obj.value.length
gapToNextAfterDiff = gapToNextAfterDiff + obj.value.length
}
afterText = afterText + obj.value
const previousDiffPoint = afterDiffMarkers[afterDiffMarkers.length - 1]?.[1] || 0
const startingPoint = previousDiffPoint + gapToNextAfterDiff
afterDiffMarkers.push([startingPoint, startingPoint + obj.value.length])
gapToNextAfterDiff = 0
previousText = previousText + obj.value
const previousDiffPoint = previousDiffMarkers[previousDiffMarkers.length - 1]?.[1] || 0
const startingPoint = previousDiffPoint + gapToNextPreviousDiff
previousDiffMarkers.push([startingPoint, startingPoint + obj.value.length])
gapToNextPreviousDiff = 0
previousText,
afterText,
previousDiffMarkers,
afterDiffMarkers,
<script>
const previousDiffMarkers = [];
const afterDiffMarkers = [];
</script>
<script>
previousDiffMarkers.push({{hunk.previousDiffMarkers | jsonStringify}})
afterDiffMarkers.push({{hunk.afterDiffMarkers | jsonStringify}})
</script>
<pre class='code'>{{hunk.before | safe}}</pre>
<pre class='code'><code data-type="before" data-hunk-index={{loop.index - 1}}>{{hunk.previousText | safe}}</code></pre>
<pre class='code'>{{hunk.after | safe}}</pre>
<pre class='code'><code data-type="after" data-hunk-index={{loop.index - 1}}>{{ hunk.afterText | safe}}</code></pre>