Fixes triple backquote style code blocks in the old reddit layout and can apply syntax highlighting.
当前为
// ==UserScript== // @name old-reddit-fenced-codeblocks-fix // @namespace Violentmonkey Scripts // @match https://www.reddit.com/* // @match https://old.reddit.com/* // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @grant GM_getValue // @grant GM_setValue // @connect reddit.com // @require https://unpkg.com/showdown/dist/showdown.min.js // @require https://unpkg.com/@highlightjs/[email protected]/highlight.min.js // @sandbox DOM // @version 0.1 // @author KerfuffleV2 // @license MIT // @description Fixes triple backquote style code blocks in the old reddit layout and can apply syntax highlighting. // ==/UserScript== const defaultConfig = { // Theme used for highlighting. See https://github.com/highlightjs/highlight.js/tree/main/src/styles highlight_theme: 'github-dark-dimmed', // Apply syntax highlighting for code blocks. highlighting: true, // Apply syntax highlighting on plaintext codeblocks (for consistent styling). highlight_plaintext: true, // Run initially when the page is loaded. autorun: true, // How long to wait for a comment to load in milliseconds. comment_load_timeout: 2500, } // See this link for possible options: https://github.com/showdownjs/showdown/wiki/Showdown-Options const sd = new showdown.Converter({ noHeaderId: true, strikethrough: true, tables: true, encodeEmails: false, }); const fencedcodere = /(?:\n|^)```([-a-zA-Z0-9_.+#]*)(?:.|\n)*?\n```/g; const contentselector = '.thing[data-type="comment"], .thing[data-type="link"]'; // End user adjustable options. let config = null; function handleLoad(resp) { if (resp.status !== 200) { return; } const pj = JSON.parse(resp.responseText); const { thing, typ, utbody } = resp.context; const body = typ == 'comment' ? pj[1].data.children[0].data.body : pj[0].data.children[0].data.selftext; utbody.innerHTML = `<div class="md">${sd.makeHtml(body)}</div>`; if (!config.highlighting) { return; } utbody.querySelectorAll('pre > code').forEach(el => { if (!Array.from(el.classList.values()).find(v => v.startsWith('language-'))) { if (!config.highlight_plaintext) { return; } el.classList.add('language-plaintext'); } hljs.highlightElement(el); }); } function handleThing(thing) { const typ = thing.getAttribute('data-type'); const url = thing.getAttribute('data-url') ?? ''; const perma = thing.getAttribute('data-permalink'); if (!typ || !perma || (typ === 'link' && !url.startsWith('/'))) { return; } const utbody = thing.querySelector('div.usertext-body'); if (!utbody || !utbody.textContent.match(fencedcodere)) { return; } // console.log(`THING(${typ}): URL=${url} -- PERMA=${perma}`); GM_xmlhttpRequest({ method: 'GET', url: `${perma}.json?raw_json=1`, timeout: config.comment_load_timeout, responseType: 'json', context: { thing, utbody, typ }, onload: handleLoad, }); } function go() { document.querySelectorAll(contentselector).forEach(handleThing); } function init(){ config = GM_getValue('config'); if (!config) { config = defaultConfig; GM_setValue('config', defaultConfig); } config.highlighting = config.highlighting && typeof hljs !== 'undefined'; config.highlight_theme = config.highlight_theme ?? defaultConfig.highlight_theme; if (config.highlighting) { const cssel = document.createElement('link'); cssel.setAttribute('rel', 'stylesheet'); cssel.setAttribute('href', `https://unpkg.com/@highlightjs/[email protected]/styles/${config.highlight_theme}.min.css`); document.head.appendChild(cssel); } GM_registerMenuCommand('Apply', go); } init(); config.autorun && go();