您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
将LeetCode题目转换为Markdown格式
// ==UserScript== // @name LeetCode题目转Markdown // @version 2025-02-01 // @description 将LeetCode题目转换为Markdown格式 // @author forward // @match https://leetcode.cn/problems/* // @icon https://www.google.com/s2/favicons?sz=64&domain=leetcode.cn // @grant none // @namespace https://gf.qytechs.cn/users/1429541 // ==/UserScript== (function() { 'use strict'; const DEBUG_MODE = false; let markdownText = ''; const style = document.createElement('style'); style.textContent = ` .leetcode2md-loading{display:inline-block;width:12px;height:12px;border:2px solid currentColor;border-radius:50%;border-top-color:transparent;animation:spin .8s linear infinite;opacity:.7} .leetcode2md-success{position:fixed;top:20px;right:20px;background:var(--success-color,#52c41a);color:#fff;padding:12px 24px;border-radius:8px;font-size:14px;z-index:10000;box-shadow:0 4px 12px rgba(0,0,0,.15);animation:slideIn .3s ease,fadeOut .3s ease 2s forwards} @keyframes spin{to{transform:rotate(360deg)}} @keyframes slideIn{from{transform:translateX(100%);opacity:0}to{transform:translateX(0);opacity:1}} @keyframes fadeOut{from{opacity:1}to{opacity:0}} `; document.head.appendChild(style); const htmlToMarkdown = (() => { const rules = [ [/<pre>([\s\S]*?)<\/pre>/g, '```\n$1\n```'], [/<ul>|<\/ul>/g, ''], [/<li>/g, '- '], [/<\/li>/g, '\n'], [/<p>([\s\S]*?)<\/p>/g, '$1\n'], [/<strong>([\s\S]*?)<\/strong>/g, '**$1**'], [/<code>([\s\S]*?)<\/code>/g, '`$1`'], [/ /g, ' '], [/<img[^>]+alt="([^"]*)"[^>]+src="([^"]+)"[^>]*>/g, ''], [/<[^>]+>/g, ''], [/\n{2,}/g, '\n\n'] ]; return html => rules.reduce((text, [pattern, replacement]) => text.replace(pattern, replacement), html).trim(); })(); const showSuccessMessage = (() => { let currentMessage = null; return () => { if (currentMessage) { currentMessage.remove(); } currentMessage = document.createElement('div'); currentMessage.className = 'leetcode2md-success'; currentMessage.textContent = '✓ 已复制到剪贴板'; document.body.appendChild(currentMessage); setTimeout(() => { currentMessage.remove(); currentMessage = null; }, 2500); }; })(); function initPlugin() { const maxAttempts = 10; let attemptCount = 0; const tryInit = () => { if (attemptCount++ >= maxAttempts) return; const titleContainer = document.querySelector('.text-title-large')?.parentElement; if (!titleContainer) { setTimeout(tryInit, 500); return; } if (titleContainer.querySelector('.leetcode2md-btn')) return; const buttonContainer = document.createElement('div'); buttonContainer.className = 'flex items-center mt-2'; const btnWrapper = document.createElement('div'); btnWrapper.className = 'leetcode2md-btn relative inline-flex items-center justify-center text-caption px-2 py-1 gap-1 rounded-full bg-fill-secondary cursor-pointer transition-colors hover:bg-fill-primary hover:text-text-primary text-sd-secondary-foreground hover:opacity-80'; btnWrapper.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1em" height="1em" fill="currentColor" class="h-3.5 w-3.5"> <path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path> <rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect> </svg> ToMD `; buttonContainer.appendChild(btnWrapper); titleContainer.appendChild(buttonContainer); btnWrapper.addEventListener('click', async function() { if (this.classList.contains('loading')) return; const originalHTML = this.innerHTML; this.innerHTML = '<div class="leetcode2md-loading"></div>处理中...'; this.classList.add('loading'); try { const title = document.querySelector('.text-title-large').textContent.trim(); const content = document.querySelector("[data-track-load='description_content']").innerHTML; await navigator.clipboard.writeText(`# ${title}\n${htmlToMarkdown(content)}`); showSuccessMessage(); } catch (error) { this.textContent = '转换失败'; setTimeout(() => this.innerHTML = originalHTML, 2000); } finally { this.classList.remove('loading'); this.innerHTML = originalHTML; } }); }; tryInit(); } const debounce = (fn, delay) => { let timeoutId; return (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => fn.apply(null, args), delay); }; }; window.addEventListener('load', initPlugin); let lastUrl = location.href; new MutationObserver(debounce(() => { const url = location.href; if (url !== lastUrl) { lastUrl = url; setTimeout(initPlugin, 500); } }, 250)).observe(document, { subtree: true, childList: true }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址