LeetCode Promlem to Markdown

Convert the LeetCode problems to markdown and copy it to the clipboard.

< Feedback on LeetCode Promlem to Markdown

Review: OK - script works, but has bugs

§
Posted: 2023-06-28

最新版力扣“获取元素失败, 重试次数过多”

§
Posted: 2023-08-14

最新版,改改代码就好了


// 添加复制按钮样式
//GM_addStyle(`
//.copy-btns { display: inline-block; }
//
//.copy-btns > button {
//    margin-left: 10px;
//    vertical-align: middle;
//    font-size: 12px;
//    background: transparent;
//    border: none;
//    border-radius: 3px;
//    box-shadow: inset 0px 0px 0px 1px rgba(var(--dsw-green-standard-rgb), 1);
//    color: rgba(var(--dsw-green-standard-rgb), 1);
//    cursor: pointer;
//    outline: none;
//}`);

GM_addStyle(`
.copy-btns { display: inline-block; }

.copy-btns > button {
    margin-left: 10px;
    vertical-align: middle;
    font-size: 12px;
    background: transparent;
    border: none;
    border-radius: 3px;
    box-shadow: inset 0px 0px 0px 1px #fb7299A0;
    color: #fb7299D0;
    cursor: pointer;
    outline: none;
}`);

const turndownService = new TurndownService({
    emDelimiter: '*',
    bulletListMarker: '-'
});
turndownService.addRule('strikethrough', {
    filter: ['pre'],
    replacement: (content, node) => '\n```txt\n' + node.innerText.trim() + '\n```\n'
});
turndownService.addRule('strikethrough', {
    filter: ['sup'],
    replacement: content => '^' + content
});

// 接收HTML字符串转成Markdown格式
const htmlToMd = htmlStr => {
    console.log('转换开始...');
    return turndownService.turndown(htmlStr.replace(/<p>&nbsp;<\/p>/g, '<br>'));
}
const getDescMd = () => htmlToMd(descEle.innerHTML);
// const getCodeMd = () => document.querySelector('input[name=lang]').value + '\n' +
//     document.querySelector('input[name=code]').value + '\n```\n';
const getCodeMd = () => document.querySelector('#editor button div div').innerHTML + '\n' +
    document.querySelector("#editor > div.flex.flex-1.flex-col.overflow-hidden.pb-2 > div.flex-1.overflow-hidden > div > div > div.overflow-guard > textarea").value + '\n```\n';
const getTitle = () => titleEle.firstElementChild.innerText;

// 查询到的节点缓存在变量中
let titleEle, descEle;
// 拼接解题模板用到的字符串
const afterDesc = '\n\n  \n\n## 解题\n\n### 方法一:\n\n#### 思路\n\n\n\n#### 代码\n\n```';
// 复制标题
const copyTitleBtn = document.createElement('button');
copyTitleBtn.innerText = '复制标题';
copyTitleBtn.addEventListener('click', copyTitleHandler);
GM_registerMenuCommand("复制标题", copyTitleHandler);
// 复制题目
const copyDescBtn = document.createElement('button');
copyDescBtn.innerText = '复制题目';
copyDescBtn.addEventListener('click', copyDescHandler);
GM_registerMenuCommand("复制题目", copyDescHandler);
// 生成解题模板并复制
const copySolnTmplBtn = document.createElement('button');
copySolnTmplBtn.innerText = '解题模板';
copySolnTmplBtn.addEventListener('click', copySolnTmplHandler);
GM_registerMenuCommand("解题模板", copySolnTmplHandler);
// 放入功能按钮
const copyBtnsEle = document.createElement('div');
copyBtnsEle.className = 'copy-btns';
copyBtnsEle.appendChild(copyTitleBtn);
copyBtnsEle.appendChild(copyDescBtn);
copyBtnsEle.appendChild(copySolnTmplBtn);

// 重试计数器
let retryCounter = 0;

// 初始化元素
function initElements(targetEle) {
    //titleEle = targetEle.querySelector('h4[data-cypress=QuestionTitle]');
    //descEle = targetEle.querySelector('div.notranslate:not(#question-detail-main-tabs)');
    titleEle = targetEle.querySelector('div.w-full.px-5.pt-5 > div > div:nth-child(1) > div.flex-1 > div');
    descEle = targetEle.querySelector('div.px-5.pt-4 > div.xFUwe');
    titleEle.appendChild(copyBtnsEle);
}

function firstInit() {
    //const targetEle = document.querySelector("div.notranslate#question-detail-main-tabs");
   // if (targetEle && targetEle.querySelector('h4[data-cypress="QuestionTitle"]') !== null) {
   //     initElements(targetEle);
   // } else {
   //     if (retryCounter++ > 10) {
   //         con/le.log('获取元素失败, 重试次数过多, 请刷新页面重试或关闭此脚本.');
   //         message.error({
   //             text: '获取元素失败, 重试次数过多, 请刷新页面重试或关闭此脚本.',
   //             duration: 2000
   //         });
   //     } else {
   //         console.log('获取元素失败, 200ms后重新获取...');
   //        setTimeout(init, 200);
   //     }
   // }
    const targetEle = document.querySelector("#qd-content > div.h-full.flex-col.ssg__qd-splitter-primary-w > div > div > div > div.flex.h-full.w-full.overflow-y-auto.rounded-b > div > div");
    if (targetEle && targetEle.querySelector('div.w-full.px-5.pt-5 > div > div:nth-child(1) > div.flex-1 > div') !== null && targetEle.querySelector('div.px-5.pt-4 > div.xFUwe') !== null) {
        initElements(targetEle);
    } else {
        if (retryCounter++ > 10) {
            console.log('获取元素失败, 重试次数过多, 请刷新页面重试或关闭此脚本.');
            message.error({
                text: '获取元素失败, 重试次数过多, 请刷新页面重试或关闭此脚本.',
                duration: 2000
            });
        } else {
            console.log('获取元素失败, 200ms后重新获取...');
            setTimeout(init, 200);
        }
    }
}

const init = () => {
    // 监听tab栏变化
    const observer = new MutationObserver((mutationList, observer) => {
        mutationList.forEach((mutation) => {
            const tabEle = mutation.addedNodes[0];
            if (mutation.type == 'childList' &&
                typeof(tabEle?.className) === 'string' &&
                tabEle.className.startsWith('description')) {
                initElements(tabEle);
            }
        });
    });
    observer.observe(document.body, { childList: true, subtree: true });
    firstInit();
}

function copyTitleHandler() {
    const title = getTitle();
    // 如果标题中有题号, 则舍弃题号取点后的部分作为短标题返回
    GM_setClipboard(title.includes('.') ? title.substring(title.lastIndexOf('.') + 2) : title);
    message.success({
        text: '复制标题成功',
        duration: 800
    });
}

function copyDescHandler() {
    GM_setClipboard(getDescMd());
    message.success({
        text: '复制题目成功',
        duration: 800
    });
}

function copySolnTmplHandler() {
    GM_setClipboard(`## 题目\n\n[${titleEle.firstElementChild.innerText}](${location.href})\n\n---\n\n${getDescMd()}${afterDesc}${getCodeMd()}`);
    message.success({
        text: '复制成功',
        duration: 800
    });
}

(() => {
    'use strict';

    window.addEventListener('load', init);
})();

Post reply

Sign in to post a reply.