diff --git a/root/static/js/syntaxhighlighter.mjs b/root/static/js/syntaxhighlighter.mjs index be84d3cee0..2131c320be 100644 --- a/root/static/js/syntaxhighlighter.mjs +++ b/root/static/js/syntaxhighlighter.mjs @@ -132,24 +132,29 @@ const processPackages = function(code) { return code.replace(/((use|package|require)<\/code> )([A-Z_a-z][0-9A-Z_a-z]*(?:::[0-9A-Z_a-z]+)*)(.*?<\/code>)/g, replace_pattern); }; -const getCodeLinesHtml = Renderer.prototype.getCodeLinesHtml; -Renderer.prototype.getCodeLinesHtml = function() { - // the syntax highlighter has a bug that strips spaces from the first line. - // replace any leading whitespace with an entity, preventing that. - // html = html.replace(/^ /, " "); - // html = html.replace(/^\t/, " "); - let html = getCodeLinesHtml.apply(this, arguments); - return processPackages.call(this, html); +const processUrls = Renderer.prototype.processUrls; +Renderer.prototype.processUrls = function(html, ...args) { + html = processPackages.apply(this, [html]); + html = processUrls.apply(this, [html, ...args]); + return html; }; const getHtml = Renderer.prototype.getHtml; -Renderer.prototype.getHtml = function() { - let html = getHtml.call(this); +Renderer.prototype.getHtml = function(...args) { + let html = getHtml.call(this, ...args); html = html.replace(/\s+(<(tbody|table|div)\b)/g, '$1'); html = html.replace(/(<\/(tbody|table|div)>)\s+/g, '$1'); return html; }; +const wrapLine = Renderer.prototype.wrapLine; +Renderer.prototype.wrapLine = function(lineIndex, lineNumber, lineHtml) { + if (lineHtml == ' ') { + lineHtml = ''; + } + return wrapLine.call(this, lineIndex, lineNumber, lineHtml); +}; + // on pod pages, set the language to perl if no other language is set CODE: for (const code of document.querySelectorAll(".pod pre > code")) { for (const className of code.classList) { @@ -231,14 +236,44 @@ for (const code of document.querySelectorAll(".content pre > code")) { config.package_target_type = source ? 'source' : 'pod'; - // highlighter strips leading blank lines, throwing off line numbers. - // add a blank line for the highlighter to strip - // const html = code.innerHTML; - // if (html.match(/^ *\n/)) { - // code.innerHTML = "\n " + html; - // } + let highlightObject = code; + + const html = code.innerHTML; + if (html.match(/^ *\n+/)) { + // highlighter strips leading blank lines, throwing off line numbers. + // use this awful hack to bypass it. depends on specific details inside + // the syntaxhighlighter module + + const fakeCode = { + className: code.className, + id: code.id, + title: code.title, + innerHTML: { + toString: function() { + return html + }, + replace: function(search, replace) { + if (search.toString() == /^[ ]*[\n]+|[\n]*[ ]*$/g.toString()) { + return html.replace(/\n$/g, ''); + } + return html.replace(search, replace); + }, + }, + }; + const parentNode = code.parentNode; + fakeCode.parentNode = { + replaceChild: function(newEl, oldEl) { + if (oldEl === fakeCode) { + oldEl = code + } + parentNode.replaceChild(newEl, oldEl); + }, + }; + + highlightObject = fakeCode; + } - SyntaxHighlighter.highlight(config, code); + SyntaxHighlighter.highlight(config, highlightObject); const pod_lines = pre.dataset.podLines; if (pod_lines) { diff --git a/root/static/less/syntaxhighlighter-theme.less b/root/static/less/syntaxhighlighter-theme.less index 0768e51323..f8a42dc6d0 100644 --- a/root/static/less/syntaxhighlighter-theme.less +++ b/root/static/less/syntaxhighlighter-theme.less @@ -22,6 +22,7 @@ .line { white-space: pre; + min-height: 1.2em; } // main table and columns