-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
95 lines (84 loc) · 2.78 KB
/
index.js
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
/* eslint prefer-template: 0 */
/* eslint no-useless-escape: 0 */
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author [email protected]
*/
var fs = require('fs');
var loaderUtils = require('loader-utils');
function replaceFilename(content, filename) {
return content.replace(/__FILE__/g, filename.replace(/\\/g, '/'));
}
function replaceLinenumber(content) {
return content
.split('\n')
.map((line, index) => line.replace(/__LINE__/g, index + 1))
.join('\n');
}
function preprocessMacros(macros) {
macros.forEach((macro) => {
const split = macro.declaration.split(/[(),]/).filter(Boolean);
macro.name = split[0].trim();
macro.args = split.slice(1).map(arg => arg.trim());
});
return macros;
}
function buildSubstitution(expression, macro) {
const split = expression.split(/[(),]/).filter(Boolean);
let result = macro.definition;
macro.args.forEach((arg, index) => {
result = result.replace(new RegExp(arg, 'g'), split[index + 1]);
});
return result;
}
function replaceMacros(content, macros) {
var result = content;
macros.forEach((macro) => {
if (macro.args.length === 0) {
// Macro has no arguments, easy
result = result.replace(new RegExp(macro.name + '\s*(\\(\\))?', 'g'),
macro.definition);
} else {
// Macro has arguments
// First retrieve the expressions to replace
const expressions = result.match(new RegExp(macro.name + '\s*\\([^\)]+\\)', 'g'));
if (expressions) {
// Then extract the parameters
expressions.forEach((expression) => {
// Build the definition with variable substitution
const substitution = buildSubstitution(expression, macro);
// Finally replace the declaration by the definition
result = result.replace(expression, substitution);
});
}
}
});
return result;
}
module.exports = function (content) {
content = content.toString('utf-8');
if (this.cacheable) this.cacheable();
var query = loaderUtils.parseQuery(this.query);
var config = {};
// Load config files
if (query.config !== undefined && query.config !== '') {
try {
config = JSON.parse(fs.readFileSync(query.config, 'utf8'));
} catch (e) {
console.error('exception:', e);
throw e;
}
}
// Replace user defined macros
if (config.macros !== undefined && config.macros.length > 0) {
config.macros = preprocessMacros(config.macros);
content = replaceMacros(content, config.macros);
}
// Replace __FILE__ by the file name
content = replaceFilename(content, this.resourcePath);
// Replace __LINE__ by the line number
content = replaceLinenumber(content);
// TODO(JD): __FUNCTION__
return content;
};
module.exports.raw = true;