您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Parse AtCoder problem statement into sections
当前为
// ==UserScript== // @name spoiled competitive programming // @namespace http://tampermonkey.net/ // @version 0.1 // @description Parse AtCoder problem statement into sections // @author Harui (totally helped by GPT-4o) // @match https://atcoder.jp/contests/*/tasks/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // Create buttons and style them const downloadButton = document.createElement('button'); downloadButton.textContent = 'Download English Markdown'; downloadButton.style.position = 'fixed'; downloadButton.style.left = '10px'; downloadButton.style.bottom = '90px'; downloadButton.style.zIndex = '1000'; downloadButton.style.padding = '10px'; downloadButton.style.backgroundColor = '#4CAF50'; downloadButton.style.color = 'white'; downloadButton.style.border = 'none'; downloadButton.style.borderRadius = '5px'; downloadButton.style.cursor = 'pointer'; const openMarkdownButton = document.createElement('button'); openMarkdownButton.textContent = 'Open English Markdown in New Tab'; openMarkdownButton.style.position = 'fixed'; openMarkdownButton.style.left = '10px'; openMarkdownButton.style.bottom = '50px'; openMarkdownButton.style.zIndex = '1000'; openMarkdownButton.style.padding = '10px'; openMarkdownButton.style.backgroundColor = '#4CAF50'; openMarkdownButton.style.color = 'white'; openMarkdownButton.style.border = 'none'; openMarkdownButton.style.borderRadius = '5px'; openMarkdownButton.style.cursor = 'pointer'; const openHtmlButton = document.createElement('button'); openHtmlButton.textContent = 'Open English HTML in New Tab'; openHtmlButton.style.position = 'fixed'; openHtmlButton.style.left = '10px'; openHtmlButton.style.bottom = '10px'; openHtmlButton.style.zIndex = '1000'; openHtmlButton.style.padding = '10px'; openHtmlButton.style.backgroundColor = '#4CAF50'; openHtmlButton.style.color = 'white'; openHtmlButton.style.border = 'none'; openHtmlButton.style.borderRadius = '5px'; openHtmlButton.style.cursor = 'pointer'; // Append the buttons to the body document.body.appendChild(downloadButton); document.body.appendChild(openMarkdownButton); document.body.appendChild(openHtmlButton); // Function to extract English parts and remove Katex, returning HTML function extractHtml() { const englishParts = document.querySelectorAll('span.lang-en'); const problemTitle = document.title; let htmlContent = `<h1>${problemTitle}</h1>\n\n`; englishParts.forEach(part => { // Clone the part to avoid modifying the original document const clone = part.cloneNode(true); // Remove "Copy" buttons const copyButtons = clone.querySelectorAll('.btn-copy, .btn-pre, .div-btn-copy'); copyButtons.forEach(button => button.remove()); // Remove Katex elements const katexElements = clone.querySelectorAll('.katex'); katexElements.forEach(katex => { const tex = katex.querySelector('.katex-mathml annotation'); if (tex) { const textNode = document.createTextNode(tex.textContent); katex.parentNode.replaceChild(textNode, katex); } }); // Append HTML content htmlContent += clone.outerHTML + '\n\n'; }); return htmlContent; } // Event listener for download button downloadButton.addEventListener('click', () => { const markdownContent = htmlToMarkdown(extractHtml()); // Create a blob and download the Markdown file const blob = new Blob([markdownContent], { type: 'text/markdown' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'atcoder_english_extract.md'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); }); // Event listener for open Markdown button openMarkdownButton.addEventListener('click', () => { const markdownContent = htmlToMarkdown(extractHtml()); // Open the Markdown content in a new tab const newTab = window.open(); newTab.document.open(); newTab.document.write('<pre>' + markdownContent + '</pre>'); newTab.document.close(); }); // Event listener for open HTML button openHtmlButton.addEventListener('click', () => { const htmlContent = extractHtml(); // Open the HTML content in a new tab const newTab = window.open(); newTab.document.open(); newTab.document.write(htmlContent); newTab.document.close(); }); // Function to convert HTML to Markdown function htmlToMarkdown(html) { // Simple conversion rules const rules = [ { regex: /<h3>(.*?)<\/h3>/g, replacement: '\n### $1\n' }, { regex: /<h2>(.*?)<\/h2>/g, replacement: '\n## $1\n' }, { regex: /<h1>(.*?)<\/h1>/g, replacement: '\n# $1\n' }, { regex: /<p>(.*?)<\/p>/g, replacement: '$1\n' }, { regex: /<ul>(.*?)<\/ul>/gs, replacement: '$1' }, { regex: /<li>(.*?)<\/li>/g, replacement: '- $1' }, { regex: /<pre.*?>(.*?)<\/pre>/gs, replacement: '\n\n``` \n$1\n```' }, { regex: /<var>(.*?)<\/var>/g, replacement: '`$1`' }, { regex: /<div.*?>(.*?)<\/div>/gs, replacement: '$1' }, { regex: /<span.*?>(.*?)<\/span>/g, replacement: '$1' }, { regex: /<section.*?>(.*?)<\/section>/gs, replacement: '$1' }, { regex: /<hr>/g, replacement: '---' }, { regex: /<br>/g, replacement: '\n' } ]; // Apply rules let markdown = html; rules.forEach(rule => { markdown = markdown.replace(rule.regex, rule.replacement); }); // Remove any remaining HTML tags markdown = markdown.replace(/<\/?[^>]+(>|$)/g, ""); return markdown.trim(); } })();