PageSourceSearch

https://tobiasduerschmid.github.io/js/blog-citation-spacing.js

js tobiasduerschmid.github.io collected 2026-10-03 10:05:43 UTC 1,626 bytes, 40 lines download raw bytes

1/* Keep optional citations from leaving gaps before punctuation or joining words. */
2(function () {
3  function prepareCitationSpacing() {
4    const content = document.querySelector('.blog-post-content');
5    if (!content) return;
6
7    const text = document.createTreeWalker(content, NodeFilter.SHOW_TEXT, {
8      acceptNode(node) {
9        return node.data && !node.parentElement.closest('.citation, .blog-citation-spacing')
10          ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
11      }
12    });
13
14    content.querySelectorAll('.citation').forEach(function (citation) {
15      text.currentNode = citation;
16      const previous = text.previousNode();
17      const spacing = previous && previous.data.match(/\s+$/);
18      if (!spacing) return;
19
20      text.currentNode = citation;
21      const next = text.nextNode();
22      // Preserve the separator before a word or opening delimiter. Otherwise,
23      // the following whitespace already separates words, or punctuation closes
24      // the phrase. Hide optional spacing separately so it is never underlined
25      // or included in the citation's clickable area.
26      if (next && !/^[\s.,;:!?…%\)\]\}”’»]/u.test(next.data)) return;
27      previous.data = previous.data.slice(0, -spacing[0].length);
28      const separator = document.createElement('span');
29      separator.className = 'blog-citation-spacing';
30      separator.textContent = spacing[0];
31      citation.before(separator);
32    });
33  }
34
35  if (document.readyState === 'loading') {
36    document.addEventListener('DOMContentLoaded', prepareCitationSpacing);
37  } else {
38    prepareCitationSpacing();
39  }
40})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.