您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
优雅打印 | 显示难度
// ==UserScript== // @name Luogu Helper // @name:zh-CN 洛谷助手 // @description Print elegantly | Show difficulty // @description:zh-CN 优雅打印 | 显示难度 // @namespace work.pythoner // @match *://*.luogu.com.cn/* // @require https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js // @run-at document-end // @grant GM_registerMenuCommand // @grant GM_xmlhttpRequest // @grant GM_listValues // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_log // @version 1.0 // @author Hanson Hu // @homepage https://blog.pythoner.work // @icon https://blog.pythoner.work/favicon.ico // @license MIT // ==/UserScript== $.noConflict(); jQuery(document).ready(function() { function getToday() { // local tz let ret = new Date().toLocaleString('sv').slice(0, 10); return ret; } function getTail(str) { let index = str.lastIndexOf('\/'); return str.substring(index + 1, str.length); } function getCache(key) { const value = GM_getValue(key); if (value === undefined) return false; const obj = JSON.parse(value); const curr = Date.now(); if (curr - obj.time > CACHE_LIFESPAN) { GM_deleteValue(key); GM_log('Deleted key ' + key); return false; } else { return obj.data; } } function setCache(key, value) { const curr = Date.now(); GM_setValue(key, JSON.stringify({data: value, time: curr})); GM_log('Added key ' + key); } function getCFDifficulty() { let ret = getCache(pnum); if (ret) return ret; const re = /CF(\d+)(\w+)/; let t1 = re.exec(pnum)[1], t2 = re.exec(pnum)[2]; GM_xmlhttpRequest({ method: 'GET', url: 'https://codeforces.com/problemset/problem/' + t1 + '/' + t2, // synchronous is not supported synchronous: true, timeout: 10000, onload: function(response) { const re = /<span.+? title="Difficulty">\s*([*0-9]+)\s*<\/span>/, html = response.responseText; ret = re.exec(html)[1]; setCache(pnum, ret); }, onerror: function(e) { console.error('Access CodeForces error ', e); }, ontimeout: function(e) { console.error('Access CodeForces timeout ', e); } }); return ret; } function showDifficulty() { let cfd = getCFDifficulty(); if (cfd && !flag) { difficulty = cfd + '/' + difficulty; flag = true; jQuery('.side a[href^="/problem/list?difficulty="] span').text(difficulty); } } function getDeferredValue() { pnum = getTail(window.location.href); title = jQuery('.header h1 span').prop('title').replace(pnum, '').trim(); problem = jQuery('.main .problem-card div').eq(1).html().trim(); difficulty = jQuery('.side a[href^="/problem/list?difficulty="] span').text().trim(); if (pnum.startsWith('CF')) showDifficulty(); } function onClickPrint() { jQuery('#app').remove(); let elem = '<h1 class="lfe-h1"><span title="' + title + '">LG' + pnum + '. ' + title + '</span></h1>'; jQuery('body').append(elem); elem = '<div><p>' + difficulty + '</p></div>'; jQuery('body').append(elem); elem = problem.replaceAll(/\sdata-v-\w+=""/g, ''); jQuery('body').append(elem); elem = '<div style="position: absolute; top: 2px; right: 2px; ' + 'font-family: Bahnschrift, Trebuchet MS, sans-serif; ' + 'font-weight: lighter; font-stretch: condensed; ' + 'font-size: 20px;">' + getToday() + '</div>'; jQuery('body').append(elem); jQuery('.lfe-h1').css({'font-size': '1.5em', 'font-weight': 'normal'}); jQuery('.lfe-h2').css('margin-bottom', '0'); jQuery('.lfe-h3').css('margin-bottom', '0'); jQuery('.sample .input').css({'border': '1px solid #eee', 'margin': '0.25em 0', 'padding': '0.25em'}); jQuery('.sample .output').css({'border': '1px solid #eee', 'margin': '0.25em 0', 'padding': '0.25em'}); jQuery('.sample .copy-btn').css('display', 'none'); jQuery('body').css({'zoom': '80%', 'padding': '2em 3em 2em 3em', 'font-size': '14px'}); } function onClickPurgeCache() { const curr = Date().now(); let arr = new Array(); for (const key of GM_listValues()) { const obj = JSON.parse(GM_getValue(key)); if (curr - obj.time > CACHE_LIFESPAN) arr.push(key); } for (const key of arr) { GM_deleteValue(key); GM_log('Deleted key ' + key); } } GM_registerMenuCommand('Prepare to print', onClickPrint); GM_registerMenuCommand('Purge cache', onClickPurgeCache); const CACHE_LIFESPAN = 30 * 86400 * 1000; let pnum, title, problem, difficulty, flag = false; // Luogu load content lazily setTimeout(getDeferredValue, 1000); // update asynchronous result setTimeout(showDifficulty, 4000); });