mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-27 20:13:32 +01:00
* Support In Document links inside of the markdown editor Fixes #17288 * Cleaning up code to reduce duplication
78 lines
2.0 KiB
TypeScript
78 lines
2.0 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
'use strict';
|
|
|
|
import * as vscode from 'vscode';
|
|
|
|
import { MarkdownEngine, IToken } from './markdownEngine';
|
|
|
|
export interface TocEntry {
|
|
slug: string;
|
|
text: string;
|
|
line: number;
|
|
location: vscode.Location;
|
|
}
|
|
|
|
export class TableOfContentProvider {
|
|
private toc: TocEntry[];
|
|
|
|
public constructor(
|
|
private engine: MarkdownEngine,
|
|
private document: vscode.TextDocument) { }
|
|
|
|
public getToc(): TocEntry[] {
|
|
if (!this.toc) {
|
|
try {
|
|
this.toc = this.buildToc(this.document);
|
|
} catch (e) {
|
|
this.toc = [];
|
|
}
|
|
}
|
|
return this.toc;
|
|
}
|
|
|
|
public lookup(fragment: string): number {
|
|
const slug = TableOfContentProvider.slugify(fragment);
|
|
for (const entry of this.getToc()) {
|
|
if (entry.slug === slug) {
|
|
return entry.line;
|
|
}
|
|
}
|
|
return NaN;
|
|
}
|
|
|
|
private buildToc(document: vscode.TextDocument): any {
|
|
const toc: TocEntry[] = [];
|
|
const tokens: IToken[] = this.engine.parse(this.document.getText());
|
|
|
|
for (const heading of tokens.filter(token => token.type === 'heading_open')) {
|
|
const lineNumber = heading.map[0];
|
|
const line = document.lineAt(lineNumber);
|
|
const href = TableOfContentProvider.slugify(line.text);
|
|
if (href) {
|
|
toc.push({
|
|
slug: href,
|
|
text: TableOfContentProvider.getHeaderText(line.text),
|
|
line: lineNumber,
|
|
location: new vscode.Location(document.uri, line.range)
|
|
});
|
|
}
|
|
}
|
|
return toc;
|
|
}
|
|
|
|
private static getHeaderText(header: string): string {
|
|
return header.replace(/^\s*(#)+\s*(.*?)\s*\1*$/, '$2').trim();
|
|
}
|
|
|
|
public static slugify(header: string): string {
|
|
return encodeURI(TableOfContentProvider.getHeaderText(header)
|
|
.toLowerCase()
|
|
.replace(/\s/g, '-'));
|
|
}
|
|
}
|
|
|