8000 Apply markdown engine to result provider (#232) · neo-chan/vscode-leetcode@4eefc70 · GitHub
[go: up one dir, main page]

Skip to content
< 8000 header class="HeaderMktg header-logged-out js-details-container js-header Details f4 py-3" role="banner" data-is-top="true" data-color-mode=light data-light-theme=light data-dark-theme=dark>

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4eefc70

Browse files
Vigilansjdneo
authored andcommitted
Apply markdown engine to result provider (LeetCode-OpenSource#232)
1 parent 3028be4 commit 4eefc70

6 files changed

+82
-33
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@
321321
"dependencies": {
322322
"fs-extra": "^6.0.1",
323323
"highlight.js": "^9.15.6",
324+
"lodash": "^4.17.11",
324325
"lodash.kebabcase": "^4.1.1",
325326
"markdown-it": "^8.4.2",
326327
"require-from-string": "^2.0.2",

src/explorer/LeetCodeTreeDataProvider.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) jdneo. All rights reserved.
22
// Licensed under the MIT license.
33

4+
import * as _ from "lodash";
45
import * as os from "os";
56
import * as path from "path";
67
import * as vscode from "vscode";
@@ -201,10 +202,10 @@ export class LeetCodeTreeDataProvider implements vscode.TreeDataProvider<LeetCod
201202
private addProblemToTreeData(problem: IProblem): void {
202203
this.putProblemToMap(this.treeData.Difficulty, problem.difficulty, problem);
203204
for (const tag of problem.tags) {
204-
this.putProblemToMap(this.treeData.Tag, this.beautifyCategoryName(tag), problem);
205+
this.putProblemToMap(this.treeData.Tag, _.startCase(tag), problem);
205206
}
206207
for (const company of problem.companies) {
207-
this.putProblemToMap(this.treeData.Company, this.beautifyCategoryName(company), problem);
208+
this.putProblemToMap(this.treeData.Company, _.startCase(company), problem);
208209
}
209210
}
210211

@@ -217,10 +218,6 @@ export class LeetCodeTreeDataProvider implements vscode.TreeDataProvider<LeetCod
217218
}
218219
}
219220

220-
private beautifyCategoryName(name: string): string {
221-
return name.split("-").map((c: string) => c[0].toUpperCase() + c.slice(1)).join(" ");
222-
}
223-
224221
private getSubCategoryNodes(map: Map<string, IProblem[]>, category: Category): LeetCodeNode[] {
225222
const subCategoryNodes: LeetCodeNode[] = Array.from(map.keys()).map((subCategory: string) => {
226223
return new LeetCodeNode(Object.assign({}, defaultProblem, {

src/webview/leetCodePreviewProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class LeetCodePreviewProvider implements Disposable {
3939
}
4040

4141
this.panel.webview.html = await this.provideHtmlContent(node);
42-
this.panel.title = node.name;
42+
this.panel.title = `${node.name}: Preview`;
4343
this.panel.reveal();
4444
}
4545

src/webview/leetCodeResultProvider.ts

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// Copyright (c) jdneo. All rights reserved.
22
// Licensed under the MIT license.
33

4+
import * as _ from "lodash";
45
import { Disposable, ExtensionContext, ViewColumn, WebviewPanel, window } from "vscode";
6+
import { markdownEngine } from "./markdownEngine";
57

68
class LeetCodeResultProvider implements Disposable {
79

@@ -12,19 +14,21 @@ class LeetCodeResultProvider implements Disposable {
1214
this.context = context;
1315
}
1416

15-
public async show(result: string): Promise<void> {
17+
public async show(resultString: string): Promise<void> {
1618
if (!this.panel) {
17-
this.panel = window.createWebviewPanel("leetcode.result", "LeetCode Results", ViewColumn.Two, {
19+
this.panel = window.createWebviewPanel("leetcode.result", "Submission Result", ViewColumn.Two, {
1820
retainContextWhenHidden: true,
1921
enableFindWidget: true,
22+
localResourceRoots: markdownEngine.localResourceRoots,
2023
});
2124

2225
this.panel.onDidDispose(() => {
2326
this.panel = undefined;
2427
}, null, this.context.subscriptions);
2528
}
2629

27-
this.panel.webview.html = await this.provideHtmlContent(result);
30+
const result: IResult = this.parseResult(resultString);
31+
this.panel.webview.html = this.getWebViewContent(result);
2832
this.panel.reveal(ViewColumn.Two);
2933
}
3034

@@ -34,19 +38,67 @@ class LeetCodeResultProvider implements Disposable {
3438
}
3539
}
3640

37-
private async provideHtmlContent(result: string): Promise<string> {
38-
return `<!DOCTYPE html>
39-
<html lang="en">
41+
private parseResult(raw: string): IResult {
42+
raw = raw.concat(" √ "); // Append a dummy sentinel to the end of raw string
43+
const regSplit: RegExp = / [×vx] ([^]+?)\n(?= [×vx] )/g;
44+
const regKeyVal: RegExp = /(.+?): ([^]*)/;
45+
const result: IResult = { messages: [] };
46+
let entry: RegExpExecArray | null;
47+
do {
48+
entry = regSplit.exec(raw);
49+
if (!entry) {
50+
continue;
51+
}
52+
const kvMatch: RegExpExecArray | null = regKeyVal.exec(entry[1]);
53+
if (kvMatch) {
54+
const key: string = _.startCase(kvMatch[1]);
55+
let value: string = kvMatch[2];
56+
if (!result[key]) {
57+
result[key] = [];
58+
}
59+
if (key === "Testcase") {
60+
value = value.slice(1, -1).replace("\\n", "\n");
61+
}
62+
result[key].push(value);
63+
} else {
64+
result.messages.push(entry[1]);
65+
}
66+
} while (entry);
67+
return result;
68+
}
69+
70+
private getWebViewContent(result: IResult): string {
71+
const styles: string = markdownEngine.getStylesHTML();
72+
const title: string = `## ${result.messages[0]}`;
73+
const messages: string[] = result.messages.slice(1).map((m: string) => `* ${m}`);
74+
const sections: string[] = Object.keys(result).filter((k: string) => k !== "messages").map((key: string) => [
75+
`### ${key}`,
76+
"```",
77+
result[key].join("\n\n"),
78+
"```",
79+
].join("\n"));
80+
const body: string = markdownEngine.render([
81+
title,
82+
...messages,
83+
...sections,
84+
].join("\n"));
85+
return `
86+
<!DOCTYPE html>
87+
<html>
4088
<head>
41-
<meta charset="UTF-8">
42-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
43-
<title>LeetCode Results</title>
89+
${styles}
4490
</head>
45-
<body>
46-
<pre>${result.trim()}</pre>
91+
<body class="vscode-body 'scrollBeyondLastLine' 'wordWrap' 'showEditorSelection'" style="tab-size:4">
92+
${body}
4793
</body>
48-
</html>`;
94+
</html>
95+
`;
4996
}
5097
}
5198

99+
interface IResult {
100+
[key: string]: string[];
101+
messages: string[];
102+
}
103+
52104
export const leetCodeResultProvider: LeetCodeResultProvider = new LeetCodeResultProvider();

src/webview/leetCodeSolutionProvider.ts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,33 @@
33

44
import { Disposable, ExtensionContext, ViewColumn, WebviewPanel, window } from "vscode";
55
import { IProblem } from "../shared";
6-
import { MarkdownEngine } from "./MarkdownEngine";
6+
import { markdownEngine } from "./markdownEngine";
77

88
class LeetCodeSolutionProvider implements Disposable {
99

1010
private context: ExtensionContext;
1111
private panel: WebviewPanel | undefined;
12-
private mdEngine: MarkdownEngine;
13-
private solution: Solution;
1412

1513
public initialize(context: ExtensionContext): void {
1614
this.context = context;
17-
this.mdEngine = new MarkdownEngine();
1815
}
1916

2017
public async show(solutionString: string, problem: IProblem): Promise<void> {
2118
if (!this.panel) {
2219
this.panel = window.createWebviewPanel("leetCode.solution", "Top Voted Solution", ViewColumn.Active, {
2320
retainContextWhenHidden: true,
2421
enableFindWidget: true,
25-
localResourceRoots: this.mdEngine.localResourceRoots,
22+
localResourceRoots: markdownEngine.localResourceRoots,
2623
});
2724

2825
this.panel.onDidDispose(() => {
2926
this.panel = undefined;
3027
}, null, this.context.subscriptions);
3128
}
3229

33-
this.solution = this.parseSolution(solutionString);
34-
this.panel.title = problem.name;
35-
this.panel.webview.html = this.getWebViewContent(this.solution);
30+
const solution: Solution = this.parseSolution(solutionString);
31+
this.panel.title = `${problem.name}: Solution`;
32+
this.panel.webview.html = this.getWebViewContent(solution);
3633
this.panel.reveal(ViewColumn.Active);
3734
}
3835

@@ -56,17 +53,17 @@ class LeetCodeSolutionProvider implements Disposable {
5653
}
5754

5855
private getWebViewContent(solution: Solution): string {
59-
const styles: string = this.mdEngine.getStylesHTML();
56+
const styles: string = markdownEngine.getStylesHTML();
6057
const { title, url, lang, author, votes } = solution;
61-
const head: string = this.mdEngine.render(`# [${title}](${url})`);
58+
const head: string = markdownEngine.render(`# [${title}](${url})`);
6259
const auth: string = `[${author}](https://leetcode.com/${author}/)`;
63-
const info: string = this.mdEngine.render([
60+
const info: string = markdownEngine.render([
6461
`| Language | Author | Votes |`,
6562
`| :------: | :------: | :------: |`,
6663
`| ${lang} | ${auth} | ${votes} |`,
6764
].join("\n"));
68-
const body: string = this.mdEngine.render(solution.body, {
69-
lang: this.solution.lang,
65+
const body: string = markdownEngine.render(solution.body, {
66+
lang: solution.lang,
7067
host: "https://discuss.leetcode.com/",
7168
});
7269
return `

src/webview/MarkdownEngine.ts renamed to src/webview/markdownEngine.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as path from "path";
88
import * as vscode from "vscode";
99
import { leetCodeChannel } from "../leetCodeChannel";
1010

11-
export class MarkdownEngine {
11+
class MarkdownEngine {
1212

1313
private readonly engine: MarkdownIt;
1414
private readonly extRoot: string; // root path of vscode built-in markdown extension
@@ -106,3 +106,5 @@ export class MarkdownEngine {
106106
};
107107
}
108108
}
109+
110+
export const markdownEngine: MarkdownEngine = new MarkdownEngine();

0 commit comments

Comments
 (0)
0