diff --git a/src/webview/leetCodeResultProvider.ts b/src/webview/leetCodeResultProvider.ts index a6574ff2..1b6d2a54 100644 --- a/src/webview/leetCodeResultProvider.ts +++ b/src/webview/leetCodeResultProvider.ts @@ -42,7 +42,7 @@ class LeetCodeResultProvider implements Disposable { - ${markdownEngine.getStylesHTML()} + ${markdownEngine.getStyles()}
${result.trim()}
diff --git a/src/webview/leetCodeSolutionProvider.ts b/src/webview/leetCodeSolutionProvider.ts index 6243af02..8a378208 100644 --- a/src/webview/leetCodeSolutionProvider.ts +++ b/src/webview/leetCodeSolutionProvider.ts @@ -53,7 +53,7 @@ class LeetCodeSolutionProvider implements Disposable { } private getWebViewContent(solution: Solution): string { - const styles: string = markdownEngine.getStylesHTML(); + const styles: string = markdownEngine.getStyles(); const { title, url, lang, author, votes } = solution; const head: string = markdownEngine.render(`# [${title}](${url})`); const auth: string = `[${author}](https://leetcode.com/${author}/)`; diff --git a/src/webview/markdownEngine.ts b/src/webview/markdownEngine.ts index b3a45a4a..8ebada23 100644 --- a/src/webview/markdownEngine.ts +++ b/src/webview/markdownEngine.ts @@ -7,39 +7,70 @@ import * as os from "os"; import * as path from "path"; import * as vscode from "vscode"; import { leetCodeChannel } from "../leetCodeChannel"; +import { isWindows } from "../utils/osUtils"; -class MarkdownEngine { +class MarkdownEngine implements vscode.Disposable { - private readonly engine: MarkdownIt; - private readonly extRoot: string; // root path of vscode built-in markdown extension + private engine: MarkdownIt; + private config: MarkdownConfiguration; + private listener: vscode.Disposable; public constructor() { - this.engine = this.initEngine(); - this.extRoot = path.join(vscode.env.appRoot, "extensions", "markdown-language-features"); + this.reload(); + this.listener = vscode.workspace.onDidChangeConfiguration((event: vscode.ConfigurationChangeEvent) => { + if (event.affectsConfiguration("markdown")) { + this.reload(); + } + }, this); } public get localResourceRoots(): vscode.Uri[] { - return [vscode.Uri.file(path.join(this.extRoot, "media"))]; + return [vscode.Uri.file(path.join(this.config.extRoot, "media"))]; } - public get styles(): vscode.Uri[] { - try { - const stylePaths: string[] = require(path.join(this.extRoot, "package.json"))["contributes"]["markdown.previewStyles"]; - return stylePaths.map((p: string) => vscode.Uri.file(path.join(this.extRoot, p)).with({ scheme: "vscode-resource" })); - } catch (error) { - leetCodeChannel.appendLine("[Error] Fail to load built-in markdown style file."); - return []; - } + public dispose(): void { + this.listener.dispose(); } - public getStylesHTML(): string { - return this.styles.map((style: vscode.Uri) => ``).join(os.EOL); + public reload(): void { + this.engine = this.initEngine(); + this.config = new MarkdownConfiguration(); } public render(md: string, env?: any): string { return this.engine.render(md, env); } + public getStyles(): string { + return [ + this.getBuiltinStyles(), + this.getSettingsStyles(), + ].join(os.EOL); + } + + private getBuiltinStyles(): string { + let styles: vscode.Uri[] = []; + try { + const stylePaths: string[] = require(path.join(this.config.extRoot, "package.json"))["contributes"]["markdown.previewStyles"]; + styles = stylePaths.map((p: string) => vscode.Uri.file(path.join(this.config.extRoot, p)).with({ scheme: "vscode-resource" })); + } catch (error) { + leetCodeChannel.appendLine("[Error] Fail to load built-in markdown style file."); + } + return styles.map((style: vscode.Uri) => ``).join(os.EOL); + } + + private getSettingsStyles(): string { + return [ + ``, + ].join(os.EOL); + } + private initEngine(): MarkdownIt { const md: MarkdownIt = new MarkdownIt({ linkify: true, @@ -107,4 +138,29 @@ class MarkdownEngine { } } +// tslint:disable-next-line: max-classes-per-file +class MarkdownConfiguration { + + public readonly extRoot: string; // root path of vscode built-in markdown extension + public readonly lineHeight: number; + public readonly fontSize: number; + public readonly fontFamily: string; + + public constructor() { + const markdownConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("markdown"); + this.extRoot = path.join(vscode.env.appRoot, "extensions", "markdown-language-features"); + this.lineHeight = Math.max(0.6, +markdownConfig.get("preview.lineHeight", NaN)); + this.fontSize = Math.max(8, +markdownConfig.get("preview.fontSize", NaN)); + this.fontFamily = this.resolveFontFamily(markdownConfig); + } + + private resolveFontFamily(config: vscode.WorkspaceConfiguration): string { + let fontFamily: string = config.get("preview.fontFamily", ""); + if (isWindows() && fontFamily === config.inspect("preview.fontFamily")!.defaultValue) { + fontFamily = `${fontFamily}, 'Microsoft Yahei UI'`; + } + return fontFamily; + } +} + export const markdownEngine: MarkdownEngine = new MarkdownEngine();