Skip to content

Commit 58fd929

Browse files
authored
feat(markdown): extend markdown syntax (#94)
1 parent d352da1 commit 58fd929

File tree

11 files changed

+221
-110
lines changed

11 files changed

+221
-110
lines changed

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
1212
"typescript.tsc.autoDetect": "off",
1313
"editor.formatOnSave": true,
14-
"cSpell.words": ["ASPNETCORE", "fluentui", "iconfont", "ings", "randomstring", "singleline", "tailwindcss"],
14+
"cSpell.words": ["ASPNETCORE", "fluentui", "iconfont", "ings", "nbsp", "randomstring", "singleline", "tailwindcss"],
1515
"json.format.enable": false,
1616
"eslint.alwaysShowStatus": true,
1717
"eslint.lintTask.enable": true,

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
- [提取图片](#提取图片)
2121
- [博文设置面板](#博文设置面板)
2222
- [闪存](#闪存)
23+
- [markdown语法扩展](#markdown语法扩展)
2324
- [vscode 版本要求](#vscode-版本要求)
2425
- [插件设置](#插件设置)
2526

@@ -167,6 +168,16 @@
167168

168169
通过本插件发布的闪存, 在尾部会显示一个vscode图标
169170

171+
### markdown语法扩展
172+
173+
本插件可以让vscode中的markdown预览支持博客园中扩展的markdown语法, 您可以通过设置来控制是否要启用此功能
174+
175+
<kbd><img height="550" src="https://img2023.cnblogs.com/blog/35695/202211/35695-20221129171437084-1034144030.png"></kbd>
176+
177+
使用示例:
178+
179+
<kbd><img height="550" src="https://img2023.cnblogs.com/blog/35695/202211/35695-20221129171115024-35740390.png"></kbd>
180+
170181
## vscode 版本要求
171182

172183
\>=1.62.0

package-lock.json

Lines changed: 107 additions & 96 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@
3434
],
3535
"main": "./dist/extension.js",
3636
"contributes": {
37+
"markdown.markdownItPlugins": true,
38+
"markdown.previewScripts": [
39+
"./dist/markdown.js"
40+
],
41+
"markdown.previewStyles": [
42+
"./dist/assets/styles/highlight-code-lines.css"
43+
],
3744
"icons": {
3845
"vscode-cnb-date": {
3946
"description": "date",
@@ -426,6 +433,28 @@
426433
90,
427434
100
428435
]
436+
},
437+
"cnblogsClientForVSCode.markdown.enableEnhancement": {
438+
"order": 6,
439+
"markdownDescription": "启用博客园markdown语法扩展",
440+
"default": true,
441+
"type": "boolean",
442+
"scope": "application"
443+
},
444+
"cnblogsClientForVSCode.markdown.enableFenceQuote": {
445+
"order": 7,
446+
"type": "boolean",
447+
"scope": "application",
448+
"default": true,
449+
"markdownDescription": "博客园markdown语法扩展: 三箭头(`<<<`)栅栏引用\n\n&nbsp;\n\n使用示例:\n\n```markdown\n\n<<<\n一段引用文字\n\n一段引用文字\n<<<\n\n```"
450+
},
451+
"cnblogsClientForVSCode.markdown.enableHighlightCodeLines": {
452+
"order": 8,
453+
"type": "boolean",
454+
"scope": "application",
455+
"default": true,
456+
"editPresentation": "singlelineText",
457+
"markdownDescription": "博客园markdown语法扩展: 代码块指定行高亮\n\n&nbsp;\n\n使用示例:\n\n```markdown\n\n```typescript {1, 3-4}\nconsole.log(1)\nconsole.log(2)\nconsole.log(3)\nconsole.log(4)\nconsole.log(5)\n```\n\n```"
429458
}
430459
}
431460
}
@@ -1006,8 +1035,9 @@
10061035
"webpack-cli": "^4.8.0"
10071036
},
10081037
"dependencies": {
1009-
"@cnblogs-gitlab/markdown-it-presets": "^1.3.1",
1038+
"@cnblogs/code-highlight-adapter": "^1.7.1",
10101039
"@cnblogs/code-quality": "^2.0.2",
1040+
"@cnblogs/markdown-it-presets": "^1.6.1",
10111041
"@fluentui/react": "^8.62.4",
10121042
"base64url": "^3.0.1",
10131043
"blob": "^0.1.0",

src/commands/pdf/post-pdf-template-builder.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Post } from '../../models/post';
22
import { PostFileMapManager } from '../../services/post-file-map';
33
import fs from 'fs';
4-
import { markdownItFactory } from '@cnblogs-gitlab/markdown-it-presets';
4+
import { markdownItFactory } from '@cnblogs/markdown-it-presets';
55
import { blogSettingsService } from '../../services/blog-settings.service';
66
import { accountService } from '../../services/account.service';
77
import { postCategoryService } from '../../services/post-category.service';
@@ -17,14 +17,14 @@ export namespace postPdfTemplateBuilder {
1717
const localFilePath = PostFileMapManager.getFilePath(postId);
1818
postBody = localFilePath ? fs.readFileSync(localFilePath).toString('utf-8') : postBody;
1919

20-
const md = markdownItFactory({
21-
codeHighlight: false,
22-
math: true,
23-
disableRules: [],
24-
html: true,
25-
});
26-
27-
const html = isMarkdown ? md.render(postBody) : postBody;
20+
const html = isMarkdown
21+
? markdownItFactory({
22+
codeHighlight: false,
23+
math: true,
24+
disableRules: [],
25+
html: true,
26+
}).render(postBody)
27+
: postBody;
2828

2929
const buildTagHtml = (): Promise<string> => {
3030
let html =

src/extension.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
} from '@/services/check-workspace';
1212
import { EditPostUriHandler } from '@/services/edit-post-uri-handler';
1313
import { IngsListWebviewProvider } from 'src/services/ings-list-webview-provider';
14+
import { extendMarkdownIt } from '@/markdown/extend-markdownIt';
1415

1516
// this method is called when your extension is activated
1617
// your extension is activated the very first time the command is executed
@@ -27,6 +28,9 @@ export function activate(context: vscode.ExtensionContext) {
2728
observeConfigurationChange();
2829
observeWorkspaceFolderChange();
2930
vscode.window.registerUriHandler(new EditPostUriHandler());
31+
return {
32+
extendMarkdownIt,
33+
};
3034
}
3135

3236
// this method is called when your extension is deactivated

src/markdown/extend-markdownIt.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Settings } from '@/services/settings.service';
2+
import { HighlightCodeLinesPlugin, MarkdownIt, MultilineBlockquotePlugin } from '@cnblogs/markdown-it-presets';
3+
4+
export const extendMarkdownIt = (md: MarkdownIt) =>
5+
md
6+
.use(MultilineBlockquotePlugin, {
7+
enable: () => Settings.isEnableMarkdownEnhancement && Settings.isEnableMarkdownFenceBlockquote,
8+
})
9+
.use(HighlightCodeLinesPlugin, {
10+
enable: () => Settings.isEnableMarkdownEnhancement && Settings.isEnableMarkdownHighlightCodeLines,
11+
});

src/markdown/markdown.entry.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { HighlightersFactory, HljsHighlighter } from '@cnblogs/code-highlight-adapter';
2+
3+
HighlightersFactory.configCodeHighlightOptions({ enableCodeLineNumber: false });
4+
5+
function highlightLines(this: void) {
6+
const bgDefinitionStyleId = 'highlightedLineBackground';
7+
if (!document.querySelector(`#${bgDefinitionStyleId}`)) {
8+
const style = document.createElement('style');
9+
style.id = bgDefinitionStyleId;
10+
style.innerHTML = `:root { --highlighted-line-bg: var(--vscode-diffEditor-insertedTextBackground) }`;
11+
document.head.append(style);
12+
}
13+
14+
const highlighter = new HljsHighlighter();
15+
document.querySelectorAll<HTMLPreElement>('pre[class*="language-"][data-lines-highlight]').forEach(preEl => {
16+
const codeEl = preEl.querySelector('code');
17+
if (!codeEl) return;
18+
if (codeEl.firstChild instanceof HTMLDivElement && codeEl.children.length === 1)
19+
codeEl.firstChild.outerHTML = codeEl.firstChild.innerHTML;
20+
highlighter.highlightLines(preEl);
21+
});
22+
}
23+
24+
window.addEventListener('vscode.markdown.updateContent', highlightLines);
25+
highlightLines();

src/services/check-workspace.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ export const observeConfigurationChange = () => {
2121
refreshPostCategoriesList();
2222

2323
if (ev.affectsConfiguration(`${Settings.prefix}.${Settings.postsListPageSizeKey}`))
24-
void refreshPostsList({ queue: true });
24+
refreshPostsList({ queue: true }).catch(() => undefined);
25+
26+
if (ev.affectsConfiguration(`${Settings.prefix}.markdown`))
27+
commands.executeCommand('markdown.preview.refresh').then(undefined, () => undefined);
2528
})
2629
);
2730
isTargetWorkspace();

src/services/settings.service.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ export class Settings {
6363
return isNumber(size) ? size : 30;
6464
}
6565

66+
static get isEnableMarkdownEnhancement() {
67+
return this.configuration.get<boolean>('markdown.enableEnhancement') ?? true;
68+
}
69+
70+
static get isEnableMarkdownFenceBlockquote() {
71+
return this.configuration.get<boolean>('markdown.enableFenceQuote') ?? true;
72+
}
73+
74+
static get isEnableMarkdownHighlightCodeLines() {
75+
return this.configuration.get<boolean>('markdown.enableHighlightCodeLines');
76+
}
77+
6678
static async setWorkspaceUri(value: Uri) {
6779
if (!value.fsPath || !(value.scheme === 'file')) throw Error('Invalid uri');
6880

0 commit comments

Comments
 (0)