Usage:
Install Templater Obsidian Plugin
Copy template_leetcode.md, getProblem.js and parseProblem.js into your templater folder
Usage:
Install Templater Obsidian Plugin
Copy template_leetcode.md, getProblem.js and parseProblem.js into your templater folder
| async function getLeetProblem(tp, url) { | |
| let titleSlug = extractProblemSlug(url); | |
| let headersList = { | |
| "Accept": "*/*", | |
| "Accept-Language": "zh-CN,zh;q=0.9", | |
| "Content-Type": "application/json", | |
| "Origin": "https://leetcode.com", | |
| "Priority": "u=1, i", | |
| "Referer": "https://leetcode.com/", | |
| "Sec-Ch-Ua": "\"Google Chrome\";v=\"135\", \"Not-A.Brand\";v=\"8\", \"Chromium\";v=\"135\"", | |
| "Sec-Ch-Ua-Arch": "\"arm\"", | |
| "Sec-Ch-Ua-Bitness": "\"64\"", | |
| "Sec-Ch-Ua-Full-Version": "\"135.0.7049.85\"", | |
| "Sec-Ch-Ua-Full-Version-List": "\"Google Chrome\";v=\"135.0.7049.85\", \"Not-A.Brand\";v=\"8.0.0.0\", \"Chromium\";v=\"135.0.7049.85\"", | |
| "Sec-Ch-Ua-Mobile": "?0", | |
| "Sec-Ch-Ua-Model": "\"\"", | |
| "Sec-Ch-Ua-Platform": "\"macOS\"", | |
| "Sec-Ch-Ua-Platform-Version": "\"15.4.0\"", | |
| "Sec-Fetch-Dest": "empty", | |
| "Sec-Fetch-Mode": "cors", | |
| "Sec-Fetch-Site": "same-origin", | |
| "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36", | |
| } | |
| let gqlBody = { | |
| query: `query questionData($titleSlug: String!) { | |
| question(titleSlug: $titleSlug) { | |
| questionId | |
| questionFrontendId | |
| boundTopicId | |
| title | |
| titleSlug | |
| content | |
| translatedTitle | |
| translatedContent | |
| isPaidOnly | |
| difficulty | |
| likes | |
| dislikes | |
| isLiked | |
| similarQuestions | |
| contributors { | |
| username | |
| profileUrl | |
| avatarUrl | |
| __typename | |
| } | |
| langToValidPlayground | |
| topicTags { | |
| name | |
| slug | |
| translatedName | |
| __typename | |
| } | |
| companyTagStats | |
| codeSnippets { | |
| lang | |
| langSlug | |
| code | |
| __typename | |
| } | |
| stats | |
| hints | |
| solution { | |
| id | |
| canSeeDetail | |
| __typename | |
| } | |
| status | |
| sampleTestCase | |
| metaData | |
| judgerAvailable | |
| judgeType | |
| mysqlSchemas | |
| enableRunCode | |
| enableTestMode | |
| envInfo | |
| libraryUrl | |
| __typename | |
| } | |
| }`, | |
| variables: { "titleSlug": titleSlug } | |
| } | |
| let bodyContent = JSON.stringify(gqlBody); | |
| let response = await tp.obsidian.request({ | |
| url: "https://leetcode.com/graphql", | |
| method: "POST", | |
| body: bodyContent, | |
| headers: headersList | |
| }); | |
| console.log(response.content); | |
| return JSON.parse(response); | |
| } | |
| function extractProblemSlug(url) { | |
| const regex = /\/problems\/([^/]+)\//; | |
| const match = url.match(regex); | |
| if (match && match[1]) { | |
| return match[1]; | |
| } else { | |
| return null; // Invalid or unsupported URL format | |
| } | |
| } | |
| module.exports = getLeetProblem; | |
| async function formatLeetCodeContent(tp, htmlContent) { | |
| // 1. Get the initial Markdown conversion | |
| let processedHtml = htmlContent.replace(/(-?\d+)<sup>(\d+)<\/sup>/g, '$1^$2'); | |
| let markdown = await tp.obsidian.htmlToMarkdown(processedHtml); | |
| // 2. Process Examples: Wrap in code blocks, remove bold from header AND content | |
| markdown = markdown.replace( | |
| /(\*\*Example \d+:\*\*)\s*([\s\S]*?)(?=\n\*\*Example|\n\*\*Constraints:|\n*$)/g, | |
| (match, header, content) => { | |
| let cleanHeader = header.replace(/\*\*/g, ''); // Remove '**' from "Example X:**" header | |
| let trimmedContent = content.trim(); | |
| // --- NEW: Clean the content *before* wrapping --- | |
| let cleanContent = trimmedContent.replace(/\*\*/g, '').replace(/`/g, ''); // Remove bold AND backticks | |
| // Return formatted block | |
| return `\n${cleanHeader}\n\n\`\`\`\n${cleanContent}\n\`\`\`\n`; | |
| } | |
| ); | |
| // 3. Process Constraints: Wrap in code block, remove bold/backticks, format exponents | |
| markdown = markdown.replace( | |
| /(\*\*Constraints:\*\*)\s*([\s\S]*?)(?=\n*$)/g, | |
| (match, header, content) => { | |
| let cleanHeader = header.replace(/\*\*/g, ''); // Remove '**' from "Constraints:" header | |
| let trimmedContent = content.trim(); | |
| // --- NEW: Clean the content *before* other formatting --- | |
| let cleanContent = trimmedContent.replace(/\*\*/g, '').replace(/`/g, ''); // Remove bold AND backticks | |
| // Now apply other formatting rules to the cleaned content | |
| cleanContent = cleanContent.replace(/^\s*-\s+/gm, ''); // Remove list markers | |
| // Return formatted block | |
| return `\n${cleanHeader}\n\n\`\`\`\n${cleanContent}\n\`\`\`\n`; | |
| } | |
| ); | |
| // 4. Clean up extra newlines | |
| return markdown.replace(/\n{3,}/g, '\n\n').trim(); | |
| } | |
| module.exports = formatLeetCodeContent; |
---
<%*
let url = await tp.system.prompt("leetcode url?");
let problem = await tp.user.getProblem(tp, url);
let question = problem.data.question;
let formattedContent = await tp.user.parseProblem(tp, question.content)
console.log(question);
tp.file.rename(question.questionId + ". " + question.title);
_%>
category:
- "[[LeetCode Daily]]"
url: <% `https://leetcode.com/problems/${question.titleSlug}/` %>
difficulty: <% question.difficulty %>
concepts:
<%*
question.topicTags.forEach(item => {
tR += `- ${item.name}\n`
}) _%>
created: <% tp.file.creation_date() %>
solved: false
hint:
---
<% formattedContent %>
<% await tp.file.move("LeetCode/" + question.questionFrontendId + ". " + question.title) %>