Created
March 20, 2018 06:12
-
-
Save bradharms/097083f2789f3d4402b042e41217f9fb to your computer and use it in GitHub Desktop.
Language-neutral file preprocessor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Preprocess a file's contents represented as a string. | |
* | |
* This will look for lines containing custom preprocessor directives embedded | |
* in a string. The directives take the form of psuedo-HTML tags, which begin | |
* with <@@ COND @@> and end with </@@>, where COND is any valid JavaScript | |
* expression that is used to test whether the text between the tags | |
* should be output or not. | |
* | |
* Within the COND expressions, the variable __ (double underscore) | |
* will be available to access the data passed to the preprocessor. | |
* | |
* Nested directive are allowed. | |
* | |
* Any characters outside of the markers is completely ignored, so you can | |
* surround them with whatever commenting syntax is appropriate for the host | |
* language. You can even add comments for the directives themselves in order | |
* to help keep track of nesting levels, etc. | |
* | |
* Lines containing directives are never output. Therefore, it is not possible | |
* to inline a directive. | |
*/ | |
function preprocess(inStr, data = {}) { | |
return Function('__', [ | |
'const out = [];', | |
...inStr.split('\n').map(line => { | |
let m; | |
return (m = /^(\s*).*<@@\s*(.*)\s*@@>/g.exec(line)) ? | |
`${m[1]}if (${m[2]}) {` : | |
(m = /^(\s*).*<\/@@>/g.exec(line)) ? | |
`${m[1]}}` : | |
(m = /^(\s*)/g.exec(line)) ? | |
`${m[1]}out.push("${ | |
line.replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0') | |
}");` : | |
''; | |
}), | |
'return out;' | |
].join('\n'))(data).join('\n'); | |
} | |
let test = ` | |
if (a == b) { | |
// <@@ !__.TEST @@> | |
console.log('a == b'); | |
// </@@> !TEST | |
} | |
if (c == d) { | |
// <@@ __.TEST @@> | |
console.log("c == \\" d"); | |
// <@@ __.TEST2 @@> | |
hello(); | |
// </@@> TEST2 | |
// </@@> TEST | |
} | |
`; | |
console.log(preprocess(test, {TEST: true, TEST2: false})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment