Skip to content

Instantly share code, notes, and snippets.

@imaustink
Last active December 1, 2017 18:34
Show Gist options
  • Save imaustink/ab691033771b184520c21e9d47ac3e9c to your computer and use it in GitHub Desktop.
Save imaustink/ab691033771b184520c21e9d47ac3e9c to your computer and use it in GitHub Desktop.
A code mod to convert helper expressions to call expressions
const fs = require('fs');
const path = require('path');
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
const glob = promisify(require('glob'));
const GLOB_PATTERN = `**/*.{md,html,js}`;
const EACH_AS_REGEX = /([^\}+]*)#each\s+([^\s]*)\s+as\s+([^\s|\}]*)/gm;
const HELPER_EXPRESSION_REGEX = /(\{+)(#if|#unless|#each|#with|log|deubgger|#eq|#is|#switch|#case|#default|joinbase|#routeCurrent|routeUrl)\s+([^\}]*)/gm;
const ARGUMENT_DELIMITER_REGEX = /,?\s+/gm;
const HELPERS_WITH_HASH_EXPRESSIONS = /#routeCurrent|routeUrl|#each|#with/;
module.exports = {
getOptions: function () {
return [];
},
run: function (directory) {
return glob(GLOB_PATTERN, { cwd: directory, ignore: ['node_modules/**', 'test/**'] }).then(fileNames => {
let fileIndex = {};
return Promise.all(fileNames.map(fileName => {
let filePath = path.join(directory, fileName);
return readFile(filePath, 'utf8').then(fileContent => fileIndex[filePath] = fileContent);
})).then(() => fileIndex);
}).then((fileIndex) => {
for(let fileName in fileIndex){
let newFileContents = replace(fileIndex[fileName]);
if(newFileContents !== null){
fileIndex[fileName] = newFileContents;
}
}
return fileIndex;
}).then((fileIndex) => {
return Promise.all(Object.keys(fileIndex).map(fileName => writeFile(fileName, fileIndex[fileName], 'utf8')));
});
}
};
function replaceAsWithHash(fileContents){
let matches = EACH_AS_REGEX.exec(fileContents);
if(matches && matches[0] && matches[1] && matches[2] && matches[3]){
fileContents = fileContents.replace(matches[0], `${matches[1]}#each(${matches[2]}, ${matches[3]}=value)`);
return replaceAsWithHash(fileContents);
}
return fileContents;
}
function replaceCallExpression(fileContents){
let matches = HELPER_EXPRESSION_REGEX.exec(fileContents);
if(matches && matches[0] && matches[1] && matches[2]){
let args = (matches[3] || '').trim();
if(HELPERS_WITH_HASH_EXPRESSIONS.test(matches[2])){
let argString = '';
args = args.split(ARGUMENT_DELIMITER_REGEX);
args.forEach((arg, i) => {
argString += arg;
let nextArg = args[i + 1];
if(nextArg){
if(arg === 'true' || nextArg === 'true' || !~arg.indexOf('=') || !~nextArg.indexOf('=')){
argString += ',';
}
argString += ' ';
}
});
args = argString;
}else{
if(matches[2] === '#is'){
matches[2] = '#eq';
}
args = args.replace(ARGUMENT_DELIMITER_REGEX, ', ');
}
fileContents = fileContents.replace(matches[0], `${matches[1]}${matches[2]}(${args})`);
return replaceCallExpression(fileContents);
}
return fileContents;
}
function replace(fileContents){
let originalFileContents = fileContents;
fileContents = replaceAsWithHash(fileContents);
fileContents = replaceCallExpression(fileContents);
return originalFileContents === fileContents ? null : fileContents;
}
function promisify(fn){
return function(){
return new Promise((resolve, reject) => {
fn.apply(fn, [...arguments, (err, result) => {
if(err){
return reject(err);
}
resolve(result);
}]);
});
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment