mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-25 01:25:36 -05:00
* Initial VS Code 1.21 file copy with patches * A few more merges * Post npm install * Fix batch of build breaks * Fix more build breaks * Fix more build errors * Fix more build breaks * Runtime fixes 1 * Get connection dialog working with some todos * Fix a few packaging issues * Copy several node_modules to package build to fix loader issues * Fix breaks from master * A few more fixes * Make tests pass * First pass of license header updates * Second pass of license header updates * Fix restore dialog issues * Remove add additional themes menu items * fix select box issues where the list doesn't show up * formatting * Fix editor dispose issue * Copy over node modules to correct location on all platforms
96 lines
2.6 KiB
TypeScript
96 lines
2.6 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import * as vscode from 'vscode';
|
|
|
|
import { MarkdownEngine } from './markdownEngine';
|
|
|
|
export class Slug {
|
|
public static fromHeading(heading: string): Slug {
|
|
const slugifiedHeading = encodeURI(heading.trim()
|
|
.toLowerCase()
|
|
.replace(/[\]\[\!\"\#\$\%\&\'\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~\`]/g, '')
|
|
.replace(/\s+/g, '-')
|
|
.replace(/^\-+/, '')
|
|
.replace(/\-+$/, ''));
|
|
|
|
return new Slug(slugifiedHeading);
|
|
}
|
|
|
|
private constructor(
|
|
public readonly value: string
|
|
) { }
|
|
|
|
public equals(other: Slug): boolean {
|
|
return this.value === other.value;
|
|
}
|
|
}
|
|
|
|
export interface TocEntry {
|
|
readonly slug: Slug;
|
|
readonly text: string;
|
|
readonly level: number;
|
|
readonly line: number;
|
|
readonly location: vscode.Location;
|
|
}
|
|
|
|
export class TableOfContentsProvider {
|
|
private toc?: TocEntry[];
|
|
|
|
public constructor(
|
|
private engine: MarkdownEngine,
|
|
private document: vscode.TextDocument
|
|
) { }
|
|
|
|
public async getToc(): Promise<TocEntry[]> {
|
|
if (!this.toc) {
|
|
try {
|
|
this.toc = await this.buildToc(this.document);
|
|
} catch (e) {
|
|
this.toc = [];
|
|
}
|
|
}
|
|
return this.toc;
|
|
}
|
|
|
|
public async lookup(fragment: string): Promise<TocEntry | undefined> {
|
|
const toc = await this.getToc();
|
|
const slug = Slug.fromHeading(fragment);
|
|
return toc.find(entry => entry.slug.equals(slug));
|
|
}
|
|
|
|
private async buildToc(document: vscode.TextDocument): Promise<TocEntry[]> {
|
|
const toc: TocEntry[] = [];
|
|
const tokens = await this.engine.parse(document.uri, document.getText());
|
|
|
|
for (const heading of tokens.filter(token => token.type === 'heading_open')) {
|
|
const lineNumber = heading.map[0];
|
|
const line = document.lineAt(lineNumber);
|
|
toc.push({
|
|
slug: Slug.fromHeading(line.text),
|
|
text: TableOfContentsProvider.getHeaderText(line.text),
|
|
level: TableOfContentsProvider.getHeaderLevel(heading.markup),
|
|
line: lineNumber,
|
|
location: new vscode.Location(document.uri, line.range)
|
|
});
|
|
}
|
|
return toc;
|
|
}
|
|
|
|
private static getHeaderLevel(markup: string): number {
|
|
if (markup === '=') {
|
|
return 1;
|
|
} else if (markup === '-') {
|
|
return 2;
|
|
} else { // '#', '##', ...
|
|
return markup.length;
|
|
}
|
|
}
|
|
|
|
private static getHeaderText(header: string): string {
|
|
return header.replace(/^\s*#+\s*(.*?)\s*#*$/, (_, word) => word.trim());
|
|
}
|
|
}
|