Skip to content

Instantly share code, notes, and snippets.

@cdpath
Created April 15, 2025 10:54
Show Gist options
  • Save cdpath/2e6813d84eb423ca6e4151d9ac6e9b3b to your computer and use it in GitHub Desktop.
Save cdpath/2e6813d84eb423ca6e4151d9ac6e9b3b to your computer and use it in GitHub Desktop.
leetcode templater

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;
Error in user YAML: (<unknown>): mapping values are not allowed in this context at line 13 column 9
---
<%* 

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:
---

Question

<% formattedContent %>

Solution

<% await tp.file.move("LeetCode/" + question.questionFrontendId + ". " + question.title) %>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment