Skip to content

Instantly share code, notes, and snippets.

@bradharms
Created March 20, 2018 06:12
Show Gist options
  • Save bradharms/097083f2789f3d4402b042e41217f9fb to your computer and use it in GitHub Desktop.
Save bradharms/097083f2789f3d4402b042e41217f9fb to your computer and use it in GitHub Desktop.
Language-neutral file preprocessor
/**
* 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