Deprecate the previewFrontMatter setting
Switch to always hiding the frontmatter and then allowing markdown-it plugins to render it properly if they wish. `previewFrontMatter: "show"` is also not very useful since it usually results in a jumble of text at the top of the file This is required with the new performance work to avoid re-tokenizing the document multiple times during rendering
This commit is contained in:
parent
e325cce9bc
commit
1bbc0e3b4d
|
@ -181,16 +181,6 @@
|
|||
"description": "%markdown.styles.dec%",
|
||||
"scope": "resource"
|
||||
},
|
||||
"markdown.previewFrontMatter": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"hide",
|
||||
"show"
|
||||
],
|
||||
"default": "hide",
|
||||
"description": "%markdown.previewFrontMatter.dec%",
|
||||
"scope": "resource"
|
||||
},
|
||||
"markdown.preview.breaks": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
|
@ -307,6 +297,7 @@
|
|||
"dependencies": {
|
||||
"highlight.js": "9.13.1",
|
||||
"markdown-it": "^8.4.2",
|
||||
"markdown-it-front-matter": "^0.1.2",
|
||||
"vscode-extension-telemetry": "0.1.0",
|
||||
"vscode-nls": "^4.0.0"
|
||||
},
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
"markdown.preview.scrollPreviewWithEditorSelection.desc": "[Deprecated] Scrolls the markdown preview to reveal the currently selected line from the editor.",
|
||||
"markdown.preview.scrollPreviewWithEditorSelection.deprecationMessage": "This setting has been replaced by 'markdown.preview.scrollPreviewWithEditor' and no longer has any effect.",
|
||||
"markdown.preview.title": "Open Preview",
|
||||
"markdown.previewFrontMatter.dec": "Sets how YAML front matter should be rendered in the markdown preview. 'hide' removes the front matter. Otherwise, the front matter is treated as markdown content.",
|
||||
"markdown.previewSide.title": "Open Preview to the Side",
|
||||
"markdown.showLockedPreviewToSide.title": "Open Locked Preview to the Side",
|
||||
"markdown.showSource.title": "Show Source",
|
||||
|
|
|
@ -12,7 +12,6 @@ export class MarkdownPreviewConfiguration {
|
|||
|
||||
public readonly scrollBeyondLastLine: boolean;
|
||||
public readonly wordWrap: boolean;
|
||||
public readonly previewFrontMatter: string;
|
||||
public readonly lineBreaks: boolean;
|
||||
public readonly doubleClickToSwitchToEditor: boolean;
|
||||
public readonly scrollEditorWithPreview: boolean;
|
||||
|
@ -36,7 +35,6 @@ export class MarkdownPreviewConfiguration {
|
|||
this.wordWrap = markdownEditorConfig['editor.wordWrap'] !== 'off';
|
||||
}
|
||||
|
||||
this.previewFrontMatter = markdownConfig.get<string>('previewFrontMatter', 'hide');
|
||||
this.scrollPreviewWithEditor = !!markdownConfig.get<boolean>('preview.scrollPreviewWithEditor', true);
|
||||
this.scrollEditorWithPreview = !!markdownConfig.get<boolean>('preview.scrollEditorWithPreview', true);
|
||||
this.lineBreaks = !!markdownConfig.get<boolean>('preview.breaks', false);
|
||||
|
|
|
@ -68,7 +68,7 @@ export class MarkdownContentProvider {
|
|||
const nonce = new Date().getTime() + '' + new Date().getMilliseconds();
|
||||
const csp = this.getCspForResource(sourceUri, nonce);
|
||||
|
||||
const body = await this.engine.render(markdownDocument, config.previewFrontMatter === 'hide');
|
||||
const body = await this.engine.render(markdownDocument);
|
||||
return `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
@ -12,13 +12,11 @@ import { Slugifier } from './slugify';
|
|||
import { SkinnyTextDocument } from './tableOfContentsProvider';
|
||||
import { getUriForLinkWithKnownExternalScheme } from './util/links';
|
||||
|
||||
const FrontMatterRegex = /^---\s*[^]*?(-{3}|\.{3})\s*/;
|
||||
const UNICODE_NEWLINE_REGEX = /\u2028|\u2029/g;
|
||||
|
||||
export class MarkdownEngine {
|
||||
private md?: MarkdownIt;
|
||||
|
||||
private firstLine?: number;
|
||||
private currentDocument?: vscode.Uri;
|
||||
private _slugCount = new Map<string, number>();
|
||||
private _cache?: {
|
||||
|
@ -69,6 +67,21 @@ export class MarkdownEngine {
|
|||
this.usePlugin(await plugin);
|
||||
}
|
||||
|
||||
const frontMatterPlugin = require('markdown-it-front-matter');
|
||||
// Extract rules from front matter plugin and apply at a lower precedence
|
||||
let fontMatterRule: any;
|
||||
frontMatterPlugin({
|
||||
block: {
|
||||
ruler: {
|
||||
before: (_id: any, _id2: any, rule: any) => { fontMatterRule = rule; }
|
||||
}
|
||||
}
|
||||
}, () => { /* noop */ });
|
||||
|
||||
this.md.block.ruler.before('fence', 'front_matter', fontMatterRule, {
|
||||
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
||||
});
|
||||
|
||||
for (const renderName of ['paragraph_open', 'heading_open', 'image', 'code_block', 'fence', 'blockquote_open', 'list_item_open']) {
|
||||
this.addLineNumberRenderer(this.md, renderName);
|
||||
}
|
||||
|
@ -89,20 +102,7 @@ export class MarkdownEngine {
|
|||
return this.md;
|
||||
}
|
||||
|
||||
private stripFrontmatter(text: string): { frontMatter?: string, body: string, lineOffset: number } {
|
||||
let offset = 0;
|
||||
const frontMatterMatch = FrontMatterRegex.exec(text);
|
||||
let frontMatter: string | undefined;
|
||||
if (frontMatterMatch) {
|
||||
frontMatter = frontMatterMatch[0];
|
||||
offset = frontMatter.split(/\r\n|\n|\r/g).length - 1;
|
||||
text = text.substr(frontMatter.length);
|
||||
}
|
||||
return { frontMatter, body: text, lineOffset: offset };
|
||||
}
|
||||
|
||||
private tokenize(document: SkinnyTextDocument, engine: MarkdownIt): Token[] {
|
||||
const { body: text, lineOffset: offset } = this.stripFrontmatter(document.getText());
|
||||
const uri = document.uri;
|
||||
if (this._cache
|
||||
&& this._cache.document.toString() === uri.toString()
|
||||
|
@ -113,15 +113,9 @@ export class MarkdownEngine {
|
|||
|
||||
this.currentDocument = document.uri;
|
||||
this._slugCount = new Map<string, number>();
|
||||
this.firstLine = offset;
|
||||
|
||||
const tokens = engine.parse(text.replace(UNICODE_NEWLINE_REGEX, ''), {}).map(token => {
|
||||
if (token.map) {
|
||||
token.map[0] += offset;
|
||||
token.map[1] += offset;
|
||||
}
|
||||
return token;
|
||||
});
|
||||
const text = document.getText();
|
||||
const tokens = engine.parse(text.replace(UNICODE_NEWLINE_REGEX, ''), {});
|
||||
this._cache = {
|
||||
tokens,
|
||||
document: uri,
|
||||
|
@ -130,10 +124,9 @@ export class MarkdownEngine {
|
|||
return tokens;
|
||||
}
|
||||
|
||||
public async render(document: SkinnyTextDocument, _stripFrontmatter: boolean): Promise<string> {
|
||||
public async render(document: SkinnyTextDocument): Promise<string> {
|
||||
const engine = await this.getEngine(document.uri);
|
||||
const html = engine.renderer.render(this.tokenize(document, engine), this.md, {});
|
||||
return html;
|
||||
return engine.renderer.render(this.tokenize(document, engine), engine, {});
|
||||
}
|
||||
|
||||
public async parse(document: SkinnyTextDocument): Promise<Token[]> {
|
||||
|
@ -146,7 +139,7 @@ export class MarkdownEngine {
|
|||
md.renderer.rules[ruleName] = (tokens: any, idx: number, options: any, env: any, self: any) => {
|
||||
const token = tokens[idx];
|
||||
if (token.map && token.map.length) {
|
||||
token.attrSet('data-line', this.firstLine + token.map[0]);
|
||||
token.attrSet('data-line', token.map[0]);
|
||||
token.attrJoin('class', 'code-line');
|
||||
}
|
||||
|
||||
|
|
|
@ -3895,6 +3895,11 @@ map-visit@^1.0.0:
|
|||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
markdown-it-front-matter@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it-front-matter/-/markdown-it-front-matter-0.1.2.tgz#e50bf56e77e6a4f5ac4ffa894d4d45ccd9896b20"
|
||||
integrity sha1-5Qv1bnfmpPWsT/qJTU1FzNmJayA=
|
||||
|
||||
markdown-it@^8.4.2:
|
||||
version "8.4.2"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54"
|
||||
|
|
Loading…
Reference in a new issue