-
Notifications
You must be signed in to change notification settings - Fork 150
/
Copy pathpug.ts
109 lines (87 loc) · 2.19 KB
/
pug.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
import detectIndent from 'detect-indent';
import pug from 'pug';
import lex from 'pug-lexer';
import type { Transformer, Options } from '../types';
// Mixins to use svelte template features
const GET_MIXINS = (indentationType: 'tab' | 'space') =>
`mixin if(condition)
%_| {#if !{condition}}
%_block
%_| {/if}
mixin else
%_| {:else}
%_block
mixin elseif(condition)
%_| {:else if !{condition}}
%_block
mixin key(expression)
%_| {#key !{expression}}
%_block
%_| {/key}
mixin each(loop)
%_| {#each !{loop}}
%_block
%_| {/each}
mixin await(promise)
%_| {#await !{promise}}
%_block
%_| {/await}
mixin then(answer)
%_| {:then !{answer}}
%_block
mixin catch(error)
%_| {:catch !{error}}
%_block
mixin html(expression)
%_| {@html !{expression}}
mixin const(expression)
%_| {@const !{expression}}
mixin debug(variables)
%_| {@debug !{variables}}`.replace(
/%_/g,
indentationType === 'tab' ? '\t' : ' ',
);
const transformer: Transformer<Options.Pug> = async ({
content,
filename,
options,
}) => {
const pugOptions = {
// needed so pug doesn't mirror boolean attributes
// and prop spreading expressions.
doctype: 'html',
compileDebug: false,
filename,
...options,
};
const { type: indentationType } = detectIndent(content);
let input = `${GET_MIXINS(indentationType ?? 'space')}\n${content}`;
const tokens = lex(input);
const extendsToken = tokens.find((token) => token.type === 'extends');
if (extendsToken) {
const lines = input.split('\n');
const [extendsLine] = lines.splice(extendsToken.loc.start.line - 1, 1);
lines.unshift(extendsLine);
input = lines.join('\n');
}
const compiled = pug.compile(
input,
pugOptions,
// @types/pug compile() returned value doesn't have `dependencies` prop
) as pug.compileTemplate & { dependencies?: string[] };
let code: string;
try {
code = compiled();
} catch (e) {
// The error message does not have much context, add more of it
if (e instanceof Error) {
e.message = `[svelte-preprocess] Pug error while preprocessing ${filename}\n\n${e.message}`;
}
throw e;
}
return {
code,
dependencies: compiled.dependencies ?? [],
};
};
export { transformer };