-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextension.js
124 lines (101 loc) · 4.46 KB
/
extension.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
const vscode = require('vscode');
const findTopHeading = require('./extension-functions/find-top-heading');
const {getSecondLevelHeading} = require('./extension-functions/get-second-level-heading');
const createTOC = require('./extension-functions/create-toc');
/**
* Activates the extension and executes custom extension code in a child async function.
* @param {vscode.ExtensionContext} context
* @returns {void}
*/
function activate(context) {
console.log('Markdown TOC is now active!');
let disposable = vscode.commands.registerCommand(
'markdown-toc.createTOC',
async function () {
const firstCharacter = 0;
const editor = vscode.window.activeTextEditor;
let topHeading = { line: -1, text: '', isHash: true, isClosedAtx: false, isToc: false };
if (editor && editor.document.languageId === 'markdown') {
if (editor.document.lineCount < 2)
{
vscode.window.showWarningMessage('Add headings to the document and try again.');
return null;
}
// 1. Find the top heading of the page, store in an object
// 2. determine whether to use hash (openAtx or ClosedAtx) or dash (alternate) headings style
topHeading = findTopHeading(editor.document.getText());
if (!topHeading.line === -1) {
vscode.window.showWarningMessage(
'No top level headings found.'
);
return null;
}
// check if the document already has a TOC and warn the user if so
let hasTOC = false;
if (topHeading.isClosedAtx) {
// if matcher finds a Closed ATX style TOC set hasTOC to true
hasTOC = editor.document.getText().match(/^## Table of Contents ##$/m) !== null;
} else if (topHeading.isHash) {
// if matcher finds an Open ATX style TOC set hasTOC to true
hasTOC = editor.document.getText().match(/^## Table of Contents$/m) !== null;
} else {
// if matcher finds a dash style TOC set hasTOC to true
const docText = editor.document.getText();
// hasTOC = docText.match(/Table of Contents\n-+?/gm) !== null
// || docText.match(/Table of Contents\r\n-+?/gm) !== null;
hasTOC = docText.match(/(?:Table of Contents)(?:\n|\r\n)(?:-+?)/gm) !== null;
}
if (hasTOC) {
vscode.window.showWarningMessage('Table of Contents already exists.');
return null;
}
// Check if there is enough content to add a TOC
if (editor.document.lineCount <= topHeading.line + 3) {
vscode.window.showWarningMessage(
'Add more content below first level heading and try again.'
);
return null;
}
// 3. iterate over the document to find and store all second level headings
const secondLevelHeadings = [];
let start = topHeading.line > -1 ? topHeading.line + 3 : 1;
for (let idx = start; idx < editor.document.lineCount; idx++) {
let firstLine = editor.document.lineAt(idx-1).text;
let secondLine = editor.document.lineAt(idx).text;
const headingObject = getSecondLevelHeading(firstLine, idx-1, secondLine, topHeading.isHash, topHeading.isClosedAtx);
if (headingObject.line !== -1) {
// add the heading object to the array if line is not -1
secondLevelHeadings.push(headingObject);
}
}
// no second level headings? no table of contents to create, give control back to user without editing
if (secondLevelHeadings.length < 1) {
vscode.window.showWarningMessage(
'No second level headings found.'
);
return null;
}
// 4. Create the TOC as a string.
let tableOfContents = createTOC(secondLevelHeadings);
// 5. Insert the TOC after top level1 content and before first existing H2 block
const edit = new vscode.WorkspaceEdit();
edit.insert(
editor.document.uri,
new vscode.Position(secondLevelHeadings[0].line, firstCharacter),
tableOfContents
);
// apply the changes
await vscode.workspace.applyEdit(edit);
vscode.window.showInformationMessage('TOC created.');
} else {
vscode.window.showWarningMessage('No Markdown file is currently open.');
}
}
);
context.subscriptions.push(disposable);
}
function deactivate() {}
module.exports = {
activate,
deactivate,
};