var glslifyBundle = require('glslify-bundle') var glslifyDeps = require('glslify-deps/sync') var nodeResolve = require('resolve') var path = require('path') var extend = require('xtend') var stackTrace = require('stack-trace') module.exports = function(arg, opts) { var isShaderString = /(void\s+main\s?\(.*\)|\n)/.test(arg) if (Array.isArray(arg)) { // template string return iface().tag.apply(null, arguments) } else if (typeof arg === 'string' && !isShaderString && opts && opts._flags) { // browserify transform return require('./transform.js').apply(this, arguments) } else if (typeof arg === 'string' && isShaderString) { // source string return iface().compile(arg, opts) } else if (typeof arg === 'string') { // source file return iface().file(arg, opts) } else throw new Error('unhandled argument type: ' + typeof arg) } module.exports.compile = function(src, opts) { return iface().compile(src, opts) } module.exports.file = function(file, opts) { return iface().file(file, opts) } function iface () { try { var basedir = path.dirname(stackTrace.get()[2].getFileName()) } catch (err) { basedir = process.cwd() } var posts = [] return { tag: tag, compile: compile, file: file } function tag(strings) { if (typeof strings === 'string') strings = [strings] var exprs = [].slice.call(arguments, 1) var parts = [] for (var i = 0; i < strings.length-1; i++) { parts.push(strings[i], exprs[i] || '') } parts.push(strings[i]) return compile(parts.join('')) } function compile(src, opts) { if (!opts) opts = {} var depper = gdeps(opts) var deps = depper.inline(src, opts.basedir || basedir) return bundle(deps) } function file(filename, opts) { if (!opts) opts = {} var depper = gdeps(opts) var deps = depper.add(path.resolve(opts.basedir || basedir, filename)) return bundle(deps) } function gdeps (opts) { if (!opts) opts = {} var depper = glslifyDeps({ cwd: opts.basedir || basedir }) var transforms = opts.transform || [] transforms = Array.isArray(transforms) ? transforms : [transforms] transforms.forEach(function(transform) { transform = Array.isArray(transform) ? transform : [transform] var name = transform[0] var opts = transform[1] || {} if (opts.post) { posts.push({ name: name, opts: opts }) } else { depper.transform(name, opts) } }) return depper } function bundle (deps) { var source = glslifyBundle(deps) posts.forEach(function (tr) { if (typeof tr.name === 'function') { var transform = tr.name } else { var target = nodeResolve.sync(tr.name, { basedir: basedir }) var transform = require(target) } var src = transform((deps && deps[0] && deps[0].file) || null, source, { post: true }) if (src) source = src }) return source } }