洛谷到 VJudge 跳转脚本

在洛谷问题页面的特定位置添加一个跳转到 VJudge 的链接

目前為 2024-10-18 提交的版本,檢視 最新版本

// ==UserScript==
// @name         洛谷到 VJudge 跳转脚本
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  在洛谷问题页面的特定位置添加一个跳转到 VJudge 的链接
// @author       Kimi
// @match        https://www.luogu.com.cn/problem/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';
    function getProblemCode() {
        const path = window.location.pathname;
        const match = path.match(/^\/problem\/([^/]+)/);
        return match ? match[1] : null;
    }
    function getVJudgeURL(problemCode) {
        let match;
        if (match = problemCode.match(/^(P|B)(\d+)$/)) {
            const prefix = '洛谷';
            return `https://vjudge.net/problem/${encodeURIComponent(`${prefix}-${problemCode}`)}`;
        }
        if (match = problemCode.match(/^(UVA)(\d+)$/)) {
            return `https://vjudge.net/problem/${encodeURIComponent(`UVA-${match[2]}`)}`;
        }
        if (match = problemCode.match(/^(CF)(\d+[A-Za-z]*)$/)) {
            return `https://vjudge.net/problem/${encodeURIComponent(`CodeForces-${match[2]}`)}`;
        }
        if (match = problemCode.match(/^(SP)(\d+)$/)) {
            const span = document.querySelector('span[title*=" - "]');
            if (span) {
                const title = span.getAttribute('title');
                const contestName = title.split(' - ')[0];
                return `https://vjudge.net/problem/${encodeURIComponent(`SPOJ-${contestName}`)}`;
            }
            return null;
        }
        if (match = problemCode.match(/^AT_(.+)$/)) {
            return `https://vjudge.net/problem/${encodeURIComponent(`AtCoder-${match[1]}`)}`;
        }
        if (match = problemCode.match(/^AT(.+)$/)) {
            return `https://vjudge.net/problem/${encodeURIComponent(`AtCoder-${match[1]}`)}`;
        }
        return null;
    }
    function injectVJudgeLink(vjudgeURL) {
        const actionDiv = document.querySelector('div.action');
        if (actionDiv) {
            const link = document.createElement('a');
            link.href = vjudgeURL;
            link.target = '_blank';
            link.style.marginLeft = '10px';
            link.textContent = '跳转至 VJudge';
            actionDiv.appendChild(link);
        }
    }
    function main() {
        const problemCode = getProblemCode();
        if (!problemCode) {
            console.warn('Luogu to VJudge Script: Unable to extract problem code.');
            return;
        }
        const vjudgeURL = getVJudgeURL(problemCode);
        if (!vjudgeURL) {
            console.warn(`Luogu to VJudge Script: No VJudge mapping found for problem code "${problemCode}".`);
            return;
        }
        injectVJudgeLink(vjudgeURL);
    }
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', main);
    } else {
        main();
    }
})();