getmdfromleetcode 1.1.1 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -39,13 +39,25 @@ const argv = yargs(hideBin(process.argv))
39
39
  description: 'Copy output to clipboard',
40
40
  default: false
41
41
  })
42
+ .option('username', {
43
+ alias: 'n',
44
+ type: 'string',
45
+ description: 'Username for specific solution author',
46
+ default: 'endlesscheng' // 设置默认用户名为endlesscheng
47
+ })
48
+ .option('solutionOnly', {
49
+ alias: 's',
50
+ type: 'boolean',
51
+ description: 'Output solution only',
52
+ default: false
53
+ })
42
54
  .help()
43
55
  .alias('help', 'h')
44
56
  .argv;
45
57
 
46
58
  // 主函数
47
59
  async function main() {
48
- const { url, english, raw, clipboard } = argv;
60
+ const { url, english, raw, clipboard, username, solutionOnly } = argv;
49
61
  const language = english ? 'english' : 'chinese';
50
62
  const rawOutput = raw;
51
63
 
@@ -54,24 +66,36 @@ async function main() {
54
66
 
55
67
  // 首先尝试通过GraphQL API获取数据
56
68
  try {
57
- questionData = await fetchProblemDataViaGraphQL(url, language);
69
+ questionData = await fetchProblemDataViaGraphQL(url, language, username);
58
70
  } catch (apiError) {
59
71
  console.error('Failed to fetch data via GraphQL API, trying to fetch from page...', apiError.message);
60
72
  // 如果API获取失败,则尝试从页面获取数据
61
- questionData = await fetchProblemDataFromPage(url, language);
73
+ questionData = await fetchProblemDataFromPage(url, language, username);
62
74
  }
63
75
 
64
76
  // 添加语言信息到 questionData
65
77
  questionData.isEnglish = english;
66
78
 
67
- // 格式化为Markdown
68
- const markdownContent = formatAsMarkdown(questionData, rawOutput);
79
+ // 根据solutionOnly参数决定输出内容
80
+ let outputContent;
81
+ if (solutionOnly) {
82
+ // 只输出题解
83
+ if (questionData.solution) {
84
+ outputContent = formatAsMarkdown(questionData, rawOutput, true); // 传递solutionOnly标志
85
+ } else {
86
+ console.log('No solution found for the given problem.');
87
+ return;
88
+ }
89
+ } else {
90
+ // 正常输出完整内容
91
+ outputContent = formatAsMarkdown(questionData, rawOutput);
92
+ }
69
93
 
70
94
  // 如果用户指定了复制到剪贴板的选项,则复制内容
71
95
  if (clipboard) {
72
96
  try {
73
97
  // 将内容写入临时文件
74
- writeFileSync('/tmp/leetcode_content.txt', markdownContent);
98
+ writeFileSync('/tmp/leetcode_content.txt', outputContent);
75
99
 
76
100
  // 根据操作系统使用不同的命令复制到剪贴板
77
101
  if (process.platform === 'darwin') {
@@ -89,11 +113,11 @@ async function main() {
89
113
  } catch (clipboardError) {
90
114
  console.error('Failed to copy content to clipboard:', clipboardError.message);
91
115
  // 即使复制到剪贴板失败,仍然输出内容
92
- console.log(markdownContent);
116
+ console.log(outputContent);
93
117
  }
94
118
  } else {
95
119
  // 正常输出内容
96
- console.log(markdownContent);
120
+ console.log(outputContent);
97
121
  }
98
122
  } catch (error) {
99
123
  console.error('Error fetching or processing problem data:', error.message);
@@ -5,7 +5,7 @@
5
5
  import * as cheerio from 'cheerio';
6
6
 
7
7
  // 将题目内容格式化为Markdown
8
- function formatAsMarkdown(question, rawOutput = false) {
8
+ function formatAsMarkdown(question, rawOutput = false, solutionOnly = false) {
9
9
  const title = question.displayTitle;
10
10
  const difficulty = question.difficulty;
11
11
  const content = question.displayContent;
@@ -144,6 +144,17 @@ function formatAsMarkdown(question, rawOutput = false) {
144
144
  }
145
145
  });
146
146
 
147
+ // 如果只输出题解
148
+ if (solutionOnly) {
149
+ if (solution && solution.content) {
150
+ // 直接返回题解内容
151
+ let solutionContent = solution.content || '';
152
+ return solutionContent;
153
+ } else {
154
+ return '没有找到题解';
155
+ }
156
+ }
157
+
147
158
  // 构建Markdown输出
148
159
  let markdown = '';
149
160
  if (title) {
@@ -200,6 +211,8 @@ function formatAsMarkdown(question, rawOutput = false) {
200
211
  // 处理HTML实体,但保留HTML标签结构
201
212
  // solutionContent = solutionContent.replace(/&lt;/g, '<').replace(/&gt;/g, '>');
202
213
 
214
+ // solutionContent = solutionContent.replace(/&lt;/g, '<').replace(/&gt;/g, '>');
215
+
203
216
  markdown += solutionContent + '\n';
204
217
  } else {
205
218
  markdown += '\n## 题解\n\n';
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  // 使用GraphQL API获取LeetCode题目数据
6
- async function fetchProblemDataViaGraphQL(url, language = 'chinese') {
6
+ async function fetchProblemDataViaGraphQL(url, language = 'chinese', username = null) {
7
7
  // 从URL中提取题目slug
8
8
  const match = url.match(/\/problems\/([^/]+)/);
9
9
  const slug = match ? match[1] : null;
@@ -35,8 +35,8 @@ async function fetchProblemDataViaGraphQL(url, language = 'chinese') {
35
35
  `;
36
36
 
37
37
  const solutionQuery = `
38
- query solutionData($slug: String!) {
39
- questionSolutionArticles(first: 1, questionSlug: $slug) {
38
+ query solutionData($slug: String!, $first: Int) {
39
+ questionSolutionArticles(first: $first, questionSlug: $slug) {
40
40
  edges {
41
41
  node {
42
42
  title
@@ -85,7 +85,7 @@ async function fetchProblemDataViaGraphQL(url, language = 'chinese') {
85
85
  },
86
86
  body: JSON.stringify({
87
87
  query: solutionQuery,
88
- variables: { slug: slug }
88
+ variables: { slug: slug, first: 20 } // 增加数量以查找特定用户
89
89
  })
90
90
  });
91
91
 
@@ -114,7 +114,23 @@ async function fetchProblemDataViaGraphQL(url, language = 'chinese') {
114
114
  if (solutionData && solutionData.data && solutionData.data.questionSolutionArticles &&
115
115
  solutionData.data.questionSolutionArticles.edges &&
116
116
  solutionData.data.questionSolutionArticles.edges.length > 0) {
117
- question.solution = solutionData.data.questionSolutionArticles.edges[0].node;
117
+
118
+ if (username) {
119
+ // 尝试查找指定用户名的题解
120
+ const userSolution = solutionData.data.questionSolutionArticles.edges.find(edge =>
121
+ edge.node.author && edge.node.author.username === username
122
+ );
123
+
124
+ // 如果找到了指定用户的题解,则使用它;否则使用第一个题解
125
+ if (userSolution) {
126
+ question.solution = userSolution.node;
127
+ } else if (solutionData.data.questionSolutionArticles.edges.length > 0) {
128
+ question.solution = solutionData.data.questionSolutionArticles.edges[0].node;
129
+ }
130
+ } else {
131
+ // 如果没有指定用户名,则使用第一个题解
132
+ question.solution = solutionData.data.questionSolutionArticles.edges[0].node;
133
+ }
118
134
  }
119
135
 
120
136
  // 添加URL到question对象
@@ -124,7 +140,7 @@ async function fetchProblemDataViaGraphQL(url, language = 'chinese') {
124
140
  }
125
141
 
126
142
  // 从页面的__NEXT_DATA__中提取题目数据
127
- async function fetchProblemDataFromPage(url, language = 'chinese') {
143
+ async function fetchProblemDataFromPage(url, language = 'chinese', username = null) {
128
144
  // 从URL中提取题目slug
129
145
  const match = url.match(/\/problems\/([^/]+)/);
130
146
  const slug = match ? match[1] : null;
@@ -183,7 +199,7 @@ async function fetchProblemDataFromPage(url, language = 'chinese') {
183
199
 
184
200
  // 单独获取题解数据,因为页面中可能不包含题解数据
185
201
  try {
186
- const solutionData = await fetchSolutionData(slug);
202
+ const solutionData = await fetchSolutionData(slug, username);
187
203
  if (solutionData) {
188
204
  question.solution = solutionData;
189
205
  }
@@ -201,12 +217,12 @@ async function fetchProblemDataFromPage(url, language = 'chinese') {
201
217
  }
202
218
 
203
219
  // 单独获取题解数据
204
- async function fetchSolutionData(slug) {
220
+ async function fetchSolutionData(slug, username = null) {
205
221
  const graphqlUrl = 'https://leetcode.cn/graphql';
206
222
 
207
223
  const solutionQuery = `
208
- query solutionData($slug: String!) {
209
- questionSolutionArticles(first: 1, questionSlug: $slug) {
224
+ query solutionData($slug: String!, $first: Int) {
225
+ questionSolutionArticles(first: $first, questionSlug: $slug) {
210
226
  edges {
211
227
  node {
212
228
  title
@@ -230,7 +246,7 @@ async function fetchSolutionData(slug) {
230
246
  },
231
247
  body: JSON.stringify({
232
248
  query: solutionQuery,
233
- variables: { slug: slug }
249
+ variables: { slug: slug, first: 20 } // 增加数量以查找特定用户
234
250
  })
235
251
  });
236
252
 
@@ -247,7 +263,23 @@ async function fetchSolutionData(slug) {
247
263
  if (solutionData.data && solutionData.data.questionSolutionArticles &&
248
264
  solutionData.data.questionSolutionArticles.edges &&
249
265
  solutionData.data.questionSolutionArticles.edges.length > 0) {
250
- return solutionData.data.questionSolutionArticles.edges[0].node;
266
+
267
+ if (username) {
268
+ // 尝试查找指定用户名的题解
269
+ const userSolution = solutionData.data.questionSolutionArticles.edges.find(edge =>
270
+ edge.node.author && edge.node.author.username === username
271
+ );
272
+
273
+ // 如果找到了指定用户的题解,则使用它;否则使用第一个题解
274
+ if (userSolution) {
275
+ return userSolution.node;
276
+ } else {
277
+ return solutionData.data.questionSolutionArticles.edges[0].node;
278
+ }
279
+ } else {
280
+ // 如果没有指定用户名,则返回第一个题解
281
+ return solutionData.data.questionSolutionArticles.edges[0].node;
282
+ }
251
283
  }
252
284
 
253
285
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "getmdfromleetcode",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "A command line tool to fetch LeetCode problem content and convert it to Markdown",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -10,7 +10,13 @@
10
10
  "scripts": {
11
11
  "start": "node index.js"
12
12
  },
13
- "keywords": ["leetcode", "markdown", "cli", "solution", "algorithm"],
13
+ "keywords": [
14
+ "leetcode",
15
+ "markdown",
16
+ "cli",
17
+ "solution",
18
+ "algorithm"
19
+ ],
14
20
  "author": "User",
15
21
  "license": "MIT",
16
22
  "dependencies": {
@@ -28,4 +34,4 @@
28
34
  "engines": {
29
35
  "node": ">=14.0.0"
30
36
  }
31
- }
37
+ }