UNPKG

2.61 kBJavaScriptView Raw
1const
2 path = require('path'),
3 glob = require('glob'),
4 fs = require('fs'),
5 pug = require('pug'),
6
7 globOptions = {
8 statCache: {},
9 symlinks: {},
10 nodir: true,
11 nocase: true
12 },
13
14 resolvePathByPattern = function (filename, basedir) {
15 const
16 separator = '-',
17 absoluteBasedir = path.resolve(basedir),
18 ext = path.extname(filename),
19 [section, ...remainingSegments] = path.basename(filename, ext).split(separator),
20 name = remainingSegments.join(separator);
21
22 if (undefined === name) {
23 return filename;
24 }
25
26 switch (section) {
27 case 'svg':
28 minimatchString = `${absoluteBasedir}/**/${name}.svg`;
29 break;
30 default:
31 minimatchString = `${absoluteBasedir}/**/${section}/**/${name}${ext || '.pug'}`;
32
33 }
34 const [matchedFilename, ...other] = glob.sync(minimatchString, globOptions);
35
36 if (other.length > 0) {
37 throw new Error(`More than one matches for include '${filename}' found: \n\t\t\t\t\t ` +
38 `${[matchedFilename, ...other].join('\n\t\t\t\t\t ')}`);
39 }
40
41 return matchedFilename;
42 },
43
44 includeFunction = function (filename, basedir, locals={}) {
45 return pug.renderFile(resolvePathByPattern(filename, basedir), locals);
46 },
47
48 postLex = function (tokens, options) {
49
50 return tokens.map((tok, index) => {
51
52 if (tok === null) {
53 return tok;
54 }
55
56 const
57 {type} = tok,
58 nextTok = tokens[index + 1];
59
60 if (type !== 'include' || nextTok === undefined || nextTok.type !== 'path') {
61 return tok;
62 }
63
64 if (/`[^`]+`|\+?\s*"[^"]+"\s*\+?|\+?\s*'[^']+'\s*\+?|#|\{[^\}]+}/.test(nextTok.val)) {
65
66 Object.assign(tok, {
67 type: 'code',
68 val: `process.pug.includeFunction(${nextTok.val}, '${options.basedir}', locals)`,
69 mustEscape: false,
70 buffer: true
71 });
72 Object.assign(tokens[index + 1], {
73 type: 'comment',
74 buffer: false
75 });
76 }
77 return tok;
78 }).filter(tok => tok !== null);
79 },
80
81 preLoad = function (value, options) {
82 if (options.resolve) {
83 const _resolve = options.resolve;
84 options.resolve = resolve(_resolve);
85 }
86 return value;
87 },
88
89 resolve = function (_resolve) {
90 return function (filename, source, options) {
91 const resolvedFilename = _resolve.apply(this, arguments);
92
93 return fs.existsSync(resolvedFilename) ? resolvedFilename : resolvePathByPattern(filename, options.basedir);
94 }
95 };
96
97process.pug = {
98 includeFunction
99};
100
101module.exports = {
102 postLex,
103 preLoad,
104 includeFunction
105};
\No newline at end of file