You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					182 lines
				
				3.1 KiB
			
		
		
			
		
	
	
					182 lines
				
				3.1 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								var util = require('util')
							 | 
						||
| 
								 | 
							
								var isProperty = require('is-property')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var INDENT_START = /[\{\[]/
							 | 
						||
| 
								 | 
							
								var INDENT_END = /[\}\]]/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// from https://mathiasbynens.be/notes/reserved-keywords
							 | 
						||
| 
								 | 
							
								var RESERVED = [
							 | 
						||
| 
								 | 
							
								  'do',
							 | 
						||
| 
								 | 
							
								  'if',
							 | 
						||
| 
								 | 
							
								  'in',
							 | 
						||
| 
								 | 
							
								  'for',
							 | 
						||
| 
								 | 
							
								  'let',
							 | 
						||
| 
								 | 
							
								  'new',
							 | 
						||
| 
								 | 
							
								  'try',
							 | 
						||
| 
								 | 
							
								  'var',
							 | 
						||
| 
								 | 
							
								  'case',
							 | 
						||
| 
								 | 
							
								  'else',
							 | 
						||
| 
								 | 
							
								  'enum',
							 | 
						||
| 
								 | 
							
								  'eval',
							 | 
						||
| 
								 | 
							
								  'null',
							 | 
						||
| 
								 | 
							
								  'this',
							 | 
						||
| 
								 | 
							
								  'true',
							 | 
						||
| 
								 | 
							
								  'void',
							 | 
						||
| 
								 | 
							
								  'with',
							 | 
						||
| 
								 | 
							
								  'await',
							 | 
						||
| 
								 | 
							
								  'break',
							 | 
						||
| 
								 | 
							
								  'catch',
							 | 
						||
| 
								 | 
							
								  'class',
							 | 
						||
| 
								 | 
							
								  'const',
							 | 
						||
| 
								 | 
							
								  'false',
							 | 
						||
| 
								 | 
							
								  'super',
							 | 
						||
| 
								 | 
							
								  'throw',
							 | 
						||
| 
								 | 
							
								  'while',
							 | 
						||
| 
								 | 
							
								  'yield',
							 | 
						||
| 
								 | 
							
								  'delete',
							 | 
						||
| 
								 | 
							
								  'export',
							 | 
						||
| 
								 | 
							
								  'import',
							 | 
						||
| 
								 | 
							
								  'public',
							 | 
						||
| 
								 | 
							
								  'return',
							 | 
						||
| 
								 | 
							
								  'static',
							 | 
						||
| 
								 | 
							
								  'switch',
							 | 
						||
| 
								 | 
							
								  'typeof',
							 | 
						||
| 
								 | 
							
								  'default',
							 | 
						||
| 
								 | 
							
								  'extends',
							 | 
						||
| 
								 | 
							
								  'finally',
							 | 
						||
| 
								 | 
							
								  'package',
							 | 
						||
| 
								 | 
							
								  'private',
							 | 
						||
| 
								 | 
							
								  'continue',
							 | 
						||
| 
								 | 
							
								  'debugger',
							 | 
						||
| 
								 | 
							
								  'function',
							 | 
						||
| 
								 | 
							
								  'arguments',
							 | 
						||
| 
								 | 
							
								  'interface',
							 | 
						||
| 
								 | 
							
								  'protected',
							 | 
						||
| 
								 | 
							
								  'implements',
							 | 
						||
| 
								 | 
							
								  'instanceof',
							 | 
						||
| 
								 | 
							
								  'NaN',
							 | 
						||
| 
								 | 
							
								  'undefined'
							 | 
						||
| 
								 | 
							
								]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var RESERVED_MAP = {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								for (var i = 0; i < RESERVED.length; i++) {
							 | 
						||
| 
								 | 
							
								  RESERVED_MAP[RESERVED[i]] = true
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var isVariable = function (name) {
							 | 
						||
| 
								 | 
							
								  return isProperty(name) && !RESERVED_MAP.hasOwnProperty(name)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var formats = {
							 | 
						||
| 
								 | 
							
								  s: function(s) {
							 | 
						||
| 
								 | 
							
								    return '' + s
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  d: function(d) {
							 | 
						||
| 
								 | 
							
								    return '' + Number(d)
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  o: function(o) {
							 | 
						||
| 
								 | 
							
								    return JSON.stringify(o)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var genfun = function() {
							 | 
						||
| 
								 | 
							
								  var lines = []
							 | 
						||
| 
								 | 
							
								  var indent = 0
							 | 
						||
| 
								 | 
							
								  var vars = {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var push = function(str) {
							 | 
						||
| 
								 | 
							
								    var spaces = ''
							 | 
						||
| 
								 | 
							
								    while (spaces.length < indent*2) spaces += '  '
							 | 
						||
| 
								 | 
							
								    lines.push(spaces+str)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var pushLine = function(line) {
							 | 
						||
| 
								 | 
							
								    if (INDENT_END.test(line.trim()[0]) && INDENT_START.test(line[line.length-1])) {
							 | 
						||
| 
								 | 
							
								      indent--
							 | 
						||
| 
								 | 
							
								      push(line)
							 | 
						||
| 
								 | 
							
								      indent++
							 | 
						||
| 
								 | 
							
								      return
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (INDENT_START.test(line[line.length-1])) {
							 | 
						||
| 
								 | 
							
								      push(line)
							 | 
						||
| 
								 | 
							
								      indent++
							 | 
						||
| 
								 | 
							
								      return
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (INDENT_END.test(line.trim()[0])) {
							 | 
						||
| 
								 | 
							
								      indent--
							 | 
						||
| 
								 | 
							
								      push(line)
							 | 
						||
| 
								 | 
							
								      return
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    push(line)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var line = function(fmt) {
							 | 
						||
| 
								 | 
							
								    if (!fmt) return line
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (arguments.length === 1 && fmt.indexOf('\n') > -1) {
							 | 
						||
| 
								 | 
							
								      var lines = fmt.trim().split('\n')
							 | 
						||
| 
								 | 
							
								      for (var i = 0; i < lines.length; i++) {
							 | 
						||
| 
								 | 
							
								        pushLine(lines[i].trim())
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      pushLine(util.format.apply(util, arguments))
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return line
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  line.scope = {}
							 | 
						||
| 
								 | 
							
								  line.formats = formats
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  line.sym = function(name) {
							 | 
						||
| 
								 | 
							
								    if (!name || !isVariable(name)) name = 'tmp'
							 | 
						||
| 
								 | 
							
								    if (!vars[name]) vars[name] = 0
							 | 
						||
| 
								 | 
							
								    return name + (vars[name]++ || '')
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  line.property = function(obj, name) {
							 | 
						||
| 
								 | 
							
								    if (arguments.length === 1) {
							 | 
						||
| 
								 | 
							
								      name = obj
							 | 
						||
| 
								 | 
							
								      obj = ''
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    name = name + ''
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (isProperty(name)) return (obj ? obj + '.' + name : name)
							 | 
						||
| 
								 | 
							
								    return obj ? obj + '[' + JSON.stringify(name) + ']' : JSON.stringify(name)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  line.toString = function() {
							 | 
						||
| 
								 | 
							
								    return lines.join('\n')
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  line.toFunction = function(scope) {
							 | 
						||
| 
								 | 
							
								    if (!scope) scope = {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var src = 'return ('+line.toString()+')'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Object.keys(line.scope).forEach(function (key) {
							 | 
						||
| 
								 | 
							
								      if (!scope[key]) scope[key] = line.scope[key]
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var keys = Object.keys(scope).map(function(key) {
							 | 
						||
| 
								 | 
							
								      return key
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var vals = keys.map(function(key) {
							 | 
						||
| 
								 | 
							
								      return scope[key]
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return Function.apply(null, keys.concat(src)).apply(null, vals)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (arguments.length) line.apply(null, arguments)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return line
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								genfun.formats = formats
							 | 
						||
| 
								 | 
							
								module.exports = genfun
							 |