-
Notifications
You must be signed in to change notification settings - Fork 98
/
Copy pathasciidoctorConfig.ts
94 lines (82 loc) · 3.38 KB
/
asciidoctorConfig.ts
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
import * as path from 'path'
import * as vscode from 'vscode'
import { Asciidoctor } from '@asciidoctor/core'
import { AsciidoctorProcessor } from '../asciidoctorProcessor'
import { getWorkspaceFolder } from '../util/workspace'
const MAX_DEPTH_SEARCH_ASCIIDOCCONFIG = 100
export interface AsciidoctorConfigProvider {
activate(registry: Asciidoctor.Extensions.Registry, documentUri: vscode.Uri): Promise<void>;
}
/**
* .asciidoctorconfig support.
*/
export class AsciidoctorConfig implements AsciidoctorConfigProvider {
private readonly prependExtension: Asciidoctor.Extensions.Preprocessor
constructor () {
const asciidoctorProcessor = AsciidoctorProcessor.getInstance()
this.prependExtension = asciidoctorProcessor.processor.Extensions.createPreprocessor('PrependConfigPreprocessorExtension', {
postConstruct: function () {
this.asciidoctorConfigContent = ''
},
process: function (doc, reader) {
if (this.asciidoctorConfigContent.length > 0) {
// otherwise an empty line at the beginning breaks level 0 detection
reader.pushInclude(this.asciidoctorConfigContent, undefined, undefined, 1, {})
}
},
}).$new()
}
public async activate (registry: Asciidoctor.Extensions.Registry, documentUri: vscode.Uri) {
await this.configureAsciidoctorConfigPrependExtension(documentUri)
registry.preprocessor(this.prependExtension)
}
private async configureAsciidoctorConfigPrependExtension (documentUri: vscode.Uri) {
const asciidoctorConfigContent = await getAsciidoctorConfigContent(documentUri)
if (asciidoctorConfigContent !== undefined) {
(this.prependExtension as any).asciidoctorConfigContent = asciidoctorConfigContent
} else {
(this.prependExtension as any).asciidoctorConfigContent = ''
}
}
}
async function exists (uri: vscode.Uri) {
try {
await vscode.workspace.fs.stat(uri)
return true
} catch (err) {
if (err && err.code === 'FileNotFound') {
return false
}
throw err
}
}
export async function getAsciidoctorConfigContent (documentUri: vscode.Uri): Promise<String | undefined> {
const workspaceFolder = getWorkspaceFolder(documentUri)
if (workspaceFolder === undefined) {
return undefined
}
const configContents: string[] = []
let currentFile: string = documentUri.fsPath
let increment = 0
while (currentFile !== undefined && currentFile !== workspaceFolder.uri.fsPath && increment < MAX_DEPTH_SEARCH_ASCIIDOCCONFIG) {
increment++
currentFile = path.dirname(currentFile)
configContents.push(await getConfigContent(currentFile, '.asciidoctorconfig.adoc'))
configContents.push(await getConfigContent(currentFile, '.asciidoctorconfig'))
}
const configContentsOrderedAndFiltered = configContents
.filter((config) => config !== undefined)
.reverse()
if (configContentsOrderedAndFiltered.length > 0) {
return configContentsOrderedAndFiltered.join('\n\n')
}
return undefined
}
async function getConfigContent (folderPath: string, configFilename: string) {
const asciidoctorConfigUri = vscode.Uri.joinPath(vscode.Uri.file(folderPath), configFilename)
if (await exists(asciidoctorConfigUri)) {
const asciidoctorConfigContent = new TextDecoder().decode(await vscode.workspace.fs.readFile(asciidoctorConfigUri))
return `:asciidoctorconfigdir: ${folderPath}\n\n${asciidoctorConfigContent.trim()}\n\n`
}
return undefined
}