返回首頁 

Greasy Fork is available in English.

LaTeX for LIHKG

This is to convert LaTeX to image in LIHKG posts


Installer ce script?
// ==UserScript==// @name         LaTeX for LIHKG// @namespace    http://tampermonkey.net/// @version      0.6// @description  This is to convert LaTeX to image in LIHKG posts// @author       CY Fung// @match        https://lihkg.com/*// @icon         https://avatars.githubusercontent.com/u/431808?s=48&v=4// @grant        none// @run-at       document-body// @license      Apache 2.0// ==/UserScript=='use strict';(function() {'use strict';/** Copyright (C) 2023 culefa.** Licensed under the Apache License, Version 2.0 (the "License"); you may not* use this file except in compliance with the License. You may obtain a copy of* the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the* License for the specific language ###erning permissions and limitations under* the License.*/// Check if the current hostname ends with 'lihkg.com'if (!location.hostname.endsWith('lihkg.com')) return;const MAX_QUERY_LENGTH = 800; // 2000 for encoded// Create an image element for LaTeX renderingconst createLatexNode = (t) => {if (typeof t != 'string') return null;const img = document.createElement('img');img.className = 'lihkg-userscript-latex';img.loading = 'lazy';let s = t.length > MAX_QUERY_LENGTH ? t.substring(0, MAX_QUERY_LENGTH) : t;img.src = `https://math.now.sh?bgcolor=auto&from=${encodeURIComponent(s)}`;let title = `[latex]${t}[/latex]`;img.setAttribute('alt', title);img.setAttribute('title', title);return img;};const validatedMap = new Map();const validateLaTeX = (t) => {let r = validatedMap.get(t);if (typeof r == 'boolean') return r;r = true;if (/\:\/\/|\:\\\\|\<(script|h5|h4|h3|h2|h1|span|div|br|pre|quote|img|table|tr|td)\>|\b(javascript)\b|\`\`\`/i.test(t)) r = false;validatedMap.set(t, r);return r;}// Process a text node to replace LaTeX tags with image elementsconst processTextNode = (textNode) => {if (!textNode) return;let textContent = textNode.textContent;if (typeof textContent === 'string' && textContent.length > 15) {} else {return;}textContent = textContent.trim();// Check if the text content is long enough and has LaTeX tagsif (textContent.length > 15) {} else {return;}if (textContent.indexOf('[latex]') < 0) return;const split = textContent.split(/\[latex\]((?:(?!\[latex\]|\[\/latex\]).)*)\[\/latex\]/g);// Check if the split array has an odd length (latex tags are found)if (split.length >= 3 && (split.length % 2) === 1) {const newNodes = split.map((t, j) => ((((j % 2) === 0) || !validateLaTeX(t)) ? document.createTextNode(t) : createLatexNode(t)));textNode.replaceWith(...newNodes);}};// Check a div element and process its text nodesconst checkDivDOM = (div) => {let textNode = div.firstChild;while (textNode) {if (textNode.nodeType === Node.TEXT_NODE) {processTextNode(textNode);}textNode = textNode.nextSibling;}}// Check a post div for LaTeX tags and process its children divsconst checkPostDiv = (postDiv) => {const html = postDiv.innerHTML;if (html.indexOf('[latex]') >= 0) {const divs = postDiv.querySelectorAll('div[class]:not(:empty), div[data-ast-root]:not(:empty)');if (divs.length >= 1) {for (const div of divs) {checkDivDOM(div);}} else {checkDivDOM(postDiv);}}};// Delayed check for processing post divsfunction delayedCheck(arr) {window.requestAnimationFrame(() => {for (const s of arr) {checkPostDiv(s);}});}// Create an observer to check for new posts and previewsconst observer = new MutationObserver((mutations) => {if (!location.pathname.startsWith('/thread/')) return;let arr = [];for (const s of document.querySelectorAll('[data-post-id]:not(.y24Yt), ._3rEWfQ3U63bl18JSaUvRX7 .GAagiRXJU88Nul1M7Ai0H:not(.y24Yt)')) {s.classList.add('y24Yt');arr.push(s);}if (arr.length >= 1) delayedCheck(arr);});// Start observing the body element for changesobserver.observe(document.body, {subtree: true,childList: true});})();