// ==UserScript== // @name lc-to-markdown-txt-html // @author wuxin0011 // @version 0.0.5 // @namespace https://github.com/wuxin0011/tampermonkey-script/tree/main/lc-to-markdown-txt-html // @description 力扣题目描述,讨论发布内容复制 复制为 markdown、txt、html 等格式 // @icon data:image/png;base64,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 // @match https://leetcode.cn/circle/discuss/* // @match https://leetcode.cn/problems/* // @match https://leetcode.cn/contest/weekly-contest-*/problems/* // @match https://leetcode.cn/contest/biweekly-contest-*/problems/* // @require https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.11/clipboard.min.js // @require https://unpkg.com/turndown@7.2.0/dist/turndown.js // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/499334/lc-to-markdown-txt-html.user.js // @updateURL https://update.greasyfork.icu/scripts/499334/lc-to-markdown-txt-html.meta.js // ==/UserScript== (function () { 'use strict'; const url = window.location.href const HTML_CONVERT = '__HTML_CONVERT__' const TXT_CONVERT = '__TXT_CONVERT__' const MARKDOWN_CONVERT = '__MARKDOWN_CONVERT__' const markdownURL = "https://stonehank.github.io/html-to-md/" const isDiscuss = () => url.indexOf('https://leetcode.cn/circle/discuss') != -1 const isProblem = () => url.indexOf('https://leetcode.cn/problems') != -1 const isContest = () => url.indexOf('https://leetcode.cn/contest/weekly-contest') != -1 || url.indexOf('https://leetcode.cn/contest/biweekly-contest') != -1 const isAutoKey = '__auto_pluging_key' + (isDiscuss() ? '__Discuss__' : isProblem() ? '__Problem__' : '__Contest__') // const use = (key) => typeof GM_getValue(key) == 'undefined' ? true : GM_getValue(key) const isUseMarkDown = () => use(MARKDOWN_CONVERT) const isUseTxt = () => use(TXT_CONVERT) const isUseHTML = () => use(HTML_CONVERT) let timerId = null let loadOk = false console.log('markdown', isUseMarkDown(), 'txt', isUseTxt(), 'html', isUseHTML()) const isUsePlugins = () => isUseHTML() || isUseMarkDown() || isUseTxt() const isUsePluginInThis = () => use(isAutoKey) // 当前页面是否使用该插件 let isFindButtonContainer = false const SUPPORT_TYPE = { 'md': 'md', 'txt': 'txt', 'html': 'html' } const buttons = [] const targetClass = 'my-button-target' const BUTTON_ID = `#${targetClass}` for (let i = 0; i < 3; i++) { const temp = document.createElement('button') temp.style.marginLeft = '10px' const type = i == 0 ? SUPPORT_TYPE['md'] : i == 1 ? SUPPORT_TYPE['txt'] : SUPPORT_TYPE['html'] temp.title = `复制为 ${type == 'md' ? 'markdown' : type} 格式` temp.id = `${BUTTON_ID}-${type}` temp.textContent = type temp.copytype = type buttons.push(temp) } const updateDisplay = (element, u) => element && element instanceof HTMLElement ? (element.style.display = u ? 'inline-block' : 'none') : '' // markdown button const markdownButton = buttons[0] updateDisplay(markdownButton, isUseMarkDown()) // txt button const txtButton = buttons[1] updateDisplay(txtButton, isUseTxt()) // html button const htmlButton = buttons[2] updateDisplay(htmlButton, isUseHTML()) function getHtmlContent(className) { const htmlContent = document.querySelector(className) return htmlContent ? htmlContent.innerHTML : '' } function updateElementShow(element) { if (!element instanceof HTMLElement) { return } element.style.display = element.style.display == 'none' ? 'inline-block' : 'none' } function runQuestionActionsContainer() { const className = '[class$=MarkdownContent]'; const questionActionsContainer = document.querySelector('[class*=QuestionActionsContainer]') markdownButton.className = 'e11vgnte0 css-yf7o-BaseButtonComponent-ThemedButton ery7n2v0' htmlButton.className = 'e11vgnte0 css-yf7o-BaseButtonComponent-ThemedButton ery7n2v0' txtButton.className = 'e11vgnte0 css-yf7o-BaseButtonComponent-ThemedButton ery7n2v0' const htmlContent = getHtmlContent(className) runCopy(questionActionsContainer, markdownButton, htmlContent, SUPPORT_TYPE['md']) runCopy(questionActionsContainer, htmlButton, htmlContent, SUPPORT_TYPE['html']) } const toMarkdown = (htmlContent) => { try { var turndownService = new TurndownService() var markdown = turndownService.turndown(htmlContent) return markdown } catch (e) { if (confirm('markdown转换失败,跳转到网站转换?')) { if (window?.navigator?.clipboard?.writeText) { window.navigator.clipboard.writeText(htmlContent).then(() => { window.open(markdownURL, '_blank') }, () => { }) } } else { console.error('convert markdown error default convert txt !', e) const d = document.createElement('div') d.innerHTML = content const txt = handlerText(d.textContent) return txt } } } function runProblems() { console.log('~~~ run problem ~~~~', url) let buttonClassName = 'relative inline-flex items-center justify-center text-caption px-2 py-1 gap-1 rounded-full bg-fill-secondary text-difficulty-easy dark:text-difficulty-easy' let className = "[data-track-load=description_content]" let titleClassName = '#qd-content [class*=text-title]' const isFlexMode = !!document.querySelector('#__next') console.log('is find', !!document.querySelector(className)) if (isContest()) { console.log('isFlexMode', isFlexMode) if (isFlexMode) { // className = ".FN9Jv" titleClassName = '#qd-content a' } else { className = '#base_content .question-content' titleClassName = '#base_content .question-title h3' } } else { // LCP 老版本的 容器 https://leetcode.cn/problems/1ybDKD/description/ if (!document.querySelector(className)) { className = ".FN9Jv" titleClassName = '#qd-content a' } } let title = document.querySelector(titleClassName) const titleTxt = title?.textContent title = title ? '