-
Notifications
You must be signed in to change notification settings - Fork 535
/
doctex.ts
76 lines (66 loc) · 2.6 KB
/
doctex.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
import * as vscode from 'vscode'
import { lw } from '../../lw'
import type { TeXElement } from '../../types'
import { outline } from './latex'
const logger = lw.log('Structure', 'DocTeX')
export async function construct(document: vscode.TextDocument): Promise<TeXElement[]> {
const content = document.getText()
if (!content) {
return []
}
const docContent = getDoc(content)
const sections = await getToC(document, docContent)
return sections
}
function getDoc(content: string) {
const mode: ('NORMAL' | 'COMMENT' | 'MACROCODE' | 'EXAMPLE')[] = ['NORMAL']
const comment = /(^|[^\\]|(?:(?<!\\)(?:\\\\)+))\^\^A.*$/gm
return content.split('\n').map(line => {
if (line.match(/%\s*\^\^A/)) {
return ''
} else if (line.match(/%\s*\\iffalse/)) {
mode.push('COMMENT')
} else if (line.match(/%\s*\\fi/) && mode[mode.length - 1] === 'COMMENT') {
mode.pop()
} else if (mode[mode.length - 1] === 'COMMENT') {
return ''
} else if (line.startsWith('%%')) {
return ''
} else if (line.startsWith('% \\begin{macrocode}')) {
mode.push('MACROCODE')
} else if (line.startsWith('% \\end{macrocode}') && mode[mode.length - 1] === 'MACROCODE') {
mode.pop()
} else if (mode[mode.length - 1] === 'MACROCODE') {
return ''
} else if (line.startsWith('%')) {
return line.slice(1).replace(comment, '$1').replaceAll('\\verb', '')
}
return ''
}).join('\n')
}
async function getToC(document: vscode.TextDocument, docContent: string) {
const ast = await lw.parser.parse.tex(docContent)
if (ast === undefined) {
logger.log('Failed parsing LaTeX AST.')
return []
}
const config = outline.refreshLaTeXModelConfig(false, ['macro', 'environment'])
const root: { children: TeXElement[] } = { children: [] }
let inAppendix = false
for (const node of ast.content) {
if (await outline.parseNode(node, [], root, document.fileName, config, {}, inAppendix)) {
inAppendix = true
}
}
let struct = root.children
struct = outline.nestNonSection(struct)
struct = outline.nestSection(struct, config)
const configuration = vscode.workspace.getConfiguration('latex-workshop')
if (configuration.get('view.outline.floats.number.enabled') as boolean) {
struct = outline.addFloatNumber(struct)
}
if (configuration.get('view.outline.numbers.enabled') as boolean) {
struct = outline.addSectionNumber(struct, config)
}
return struct
}