Skip to content

Instantly share code, notes, and snippets.

@tadatuta
Created December 6, 2014 20:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tadatuta/78228e4471b031c223ec to your computer and use it in GitHub Desktop.
Save tadatuta/78228e4471b031c223ec to your computer and use it in GitHub Desktop.
bem-tools: php to html tech
var BEM = require('bem'),
Q = BEM.require('q'),
VM = require('vm'),
SPAWN = require('child_process').spawn;
function strEscape(s) {
return s.replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
}
exports.API_VER = 2;
exports.techMixin = {
// magic double escaper. passing data thru platforms!
packData : function(s) {
return strEscape(this.innerPackData(s));
},
innerPackData : function(s) {
return [
'json_decode(\"',
JSON.stringify(s)
.replace(/[\\"']/g, '\\$&')
.replace(/\u0000/g, '\\0'),
'\", 1)'
].join('');
},
runPhpCode : function(code) {
code = Array.isArray(code) ? code : [code];
code = ['<?php'].concat(code).join('\n');
var php = SPAWN('php'),
html = '',
errs = '',
defer = Q.defer();
php.stdout.on('data', function(data) {
html += data.toString();
});
php.stderr.on('data', function(data) {
errs += data.toString();
});
php.on('close', function(code) {
if (errs || code !== 0) {
errs = errs ? [errs] : [];
code && errs.unshift('php process exited with code ' + code + '\\n');
}
defer.resolve(errs + html);
});
php.stdin.write(code);
php.stdin.end();
return defer.promise;
},
getBemjson : function(prefix) {
var path = this.getPath(prefix, 'bemjson.js');
return BEM.util.readFile(path)
.then(function(c) {
return VM.runInThisContext(c, path);
});
},
getPhpCode : function(path, bemjson) {
return [
'$res = "";',
// dumping thing for debuggin' purpose
'function d () { return call_user_func_array(\'\\BEM\\d\', func_get_args()); }',
// this is a splitter between stdout (render results) and stderr (debugging purposes)
'register_shutdown_function(function() use (&$res) {',
' $output = ob_get_clean();',
' $stderr = fopen(\'php://stderr\', \'w\');',
' fwrite($stderr, $output);',
' fclose($stderr);',
' echo $res;',
'});',
'require "' + path.replace(/html$/, 'bh.php') + '";',
'ob_start();', // catch output (to print as well as console.log does)
'$res = $bh->apply(' + this.innerPackData(bemjson) + ');'
];
},
getHtml : function(path, bemjson) {
var _this = this;
return Q.when(bemjson)
.then(function(bemjson) {
return _this.runPhpCode(_this.getPhpCode(path, bemjson));
});
},
getCreateResult : function(path, suffix, vars) {
return this.getHtml(path, this.getBemjson(vars.Prefix));
},
storeCreateResult : function(path, suffix, res, force) {
// always overwrite html files
return this.__base(path, suffix, res, true);
},
getDependencies : function() {
return ['bemjson.js', 'bh.php'];
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment