-
-
Notifications
You must be signed in to change notification settings - Fork 44
/
index.ts
125 lines (119 loc) · 4.16 KB
/
index.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
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
125
import type {
AstPath,
Doc,
Options,
Parser,
ParserOptions,
Plugin,
Printer,
RequiredOptions,
SupportLanguage,
SupportOptions
} from 'prettier';
import type { Token } from 'pug-lexer';
import * as lex from 'pug-lexer';
import { createLogger, Logger, LogLevel } from './logger';
import type { PugParserOptions } from './options';
import { options as pugOptions } from './options';
import { convergeOptions } from './options/converge';
import type { PugPrinterOptions } from './printer';
import { PugPrinter } from './printer';
const logger: Logger = createLogger(console);
if (process.env.NODE_ENV === 'test') {
logger.setLogLevel(LogLevel.DEBUG);
}
/** Ast path stack entry. */
interface AstPathStackEntry {
content: string;
tokens: Token[];
}
/** The plugin object that is picked up by prettier. */
export const plugin: Plugin = {
languages: [
{
name: 'Pug',
parsers: ['pug'],
tmScope: 'text.jade',
aceMode: 'jade',
codemirrorMode: 'pug',
codemirrorMimeType: 'text/x-pug',
extensions: ['.jade', '.pug'],
linguistLanguageId: 179,
vscodeLanguageIds: ['jade', 'pug']
}
],
/* eslint-disable jsdoc/require-jsdoc */
parsers: {
pug: {
parse(text: string, parsers: { [parserName: string]: Parser }, options: ParserOptions): AstPathStackEntry {
logger.debug('[parsers:pug:parse]:', { text });
let trimmedAndAlignedContent: string = text.replace(/^\s*\n/, '');
const contentIndentation: RegExpExecArray | null = /^\s*/.exec(trimmedAndAlignedContent);
if (contentIndentation?.[0]) {
const contentIndentationRegex: RegExp = new RegExp(`(^|\\n)${contentIndentation[0]}`, 'g');
trimmedAndAlignedContent = trimmedAndAlignedContent.replace(contentIndentationRegex, '$1');
}
const content: string = trimmedAndAlignedContent;
const tokens: lex.Token[] = lex(content);
// logger.debug('[parsers:pug:parse]: tokens', JSON.stringify(tokens, undefined, 2));
// const ast: AST = parse(tokens, {});
// logger.debug('[parsers:pug:parse]: ast', JSON.stringify(ast, undefined, 2));
return { content, tokens };
},
astFormat: 'pug-ast',
hasPragma(text: string): boolean {
return text.startsWith('//- @prettier\n') || text.startsWith('//- @format\n');
},
locStart(node: unknown): number {
logger.debug('[parsers:pug:locStart]:', { node });
return 0;
},
locEnd(node: unknown): number {
logger.debug('[parsers:pug:locEnd]:', { node });
return 0;
},
preprocess(text: string, options: ParserOptions): string {
logger.debug('[parsers:pug:preprocess]:', { text });
return text;
}
}
},
printers: {
'pug-ast': {
print(path: AstPath, options: ParserOptions & PugParserOptions, print: (path: AstPath) => Doc): Doc {
const entry: AstPathStackEntry = path.stack[0];
const { content, tokens } = entry;
const pugOptions: PugPrinterOptions = convergeOptions(options);
const printer: PugPrinter = new PugPrinter(content, tokens, pugOptions);
const result: string = printer.build();
logger.debug('[printers:pug-ast:print]:', result);
return result;
},
embed(
path: AstPath,
print: (path: AstPath) => Doc,
textToDoc: (text: string, options: Options) => Doc,
options: ParserOptions
): Doc | null {
// logger.debug('[printers:pug-ast:embed]:', JSON.stringify(path, undefined, 2));
return null;
},
insertPragma(text: string): string {
return `//- @prettier\n${text}`;
}
}
},
/* eslint-enable jsdoc/require-jsdoc */
options: pugOptions,
defaultOptions: {}
};
/** The languages that are picked up by prettier. */
export const languages: SupportLanguage[] | undefined = plugin.languages;
/** The parsers object that is picked up by prettier. */
export const parsers: { [parserName: string]: Parser } | undefined = plugin.parsers;
/** The printers object that is picked up by prettier. */
export const printers: { [astFormat: string]: Printer } | undefined = plugin.printers;
/** The options object that is picked up by prettier. */
export const options: SupportOptions | undefined = plugin.options;
/** The default options object that is picked up by prettier. */
export const defaultOptions: Partial<RequiredOptions> | undefined = plugin.defaultOptions;