diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2019-10-06 21:37:45 +0200 | 
|---|---|---|
| committer | Dimitri Staessens <dimitri@ouroboros.rocks> | 2019-10-06 21:37:45 +0200 | 
| commit | 3c51c3be85bb0d1bdb87ea0d6632f1c256912f27 (patch) | |
| tree | c7ccc8279b12c4f7bdbbb4270d617e48f51722e4 /node_modules/snapdragon/lib | |
| parent | 412c104bebc507bea9c94fd53b5bdc4b64cbfe31 (diff) | |
| download | website-3c51c3be85bb0d1bdb87ea0d6632f1c256912f27.tar.gz website-3c51c3be85bb0d1bdb87ea0d6632f1c256912f27.zip | |
build: Add some required modules for node
Diffstat (limited to 'node_modules/snapdragon/lib')
| -rw-r--r-- | node_modules/snapdragon/lib/compiler.js | 177 | ||||
| -rw-r--r-- | node_modules/snapdragon/lib/parser.js | 533 | ||||
| -rw-r--r-- | node_modules/snapdragon/lib/position.js | 14 | ||||
| -rw-r--r-- | node_modules/snapdragon/lib/source-maps.js | 145 | ||||
| -rw-r--r-- | node_modules/snapdragon/lib/utils.js | 48 | 
5 files changed, 917 insertions, 0 deletions
| diff --git a/node_modules/snapdragon/lib/compiler.js b/node_modules/snapdragon/lib/compiler.js new file mode 100644 index 0000000..0ce9d21 --- /dev/null +++ b/node_modules/snapdragon/lib/compiler.js @@ -0,0 +1,177 @@ +'use strict'; + +var use = require('use'); +var define = require('define-property'); +var debug = require('debug')('snapdragon:compiler'); +var utils = require('./utils'); + +/** + * Create a new `Compiler` with the given `options`. + * @param {Object} `options` + */ + +function Compiler(options, state) { +  debug('initializing', __filename); +  this.options = utils.extend({source: 'string'}, options); +  this.state = state || {}; +  this.compilers = {}; +  this.output = ''; +  this.set('eos', function(node) { +    return this.emit(node.val, node); +  }); +  this.set('noop', function(node) { +    return this.emit(node.val, node); +  }); +  this.set('bos', function(node) { +    return this.emit(node.val, node); +  }); +  use(this); +} + +/** + * Prototype methods + */ + +Compiler.prototype = { + +  /** +   * Throw an error message with details including the cursor position. +   * @param {String} `msg` Message to use in the Error. +   */ + +  error: function(msg, node) { +    var pos = node.position || {start: {column: 0}}; +    var message = this.options.source + ' column:' + pos.start.column + ': ' + msg; + +    var err = new Error(message); +    err.reason = msg; +    err.column = pos.start.column; +    err.source = this.pattern; + +    if (this.options.silent) { +      this.errors.push(err); +    } else { +      throw err; +    } +  }, + +  /** +   * Define a non-enumberable property on the `Compiler` instance. +   * +   * ```js +   * compiler.define('foo', 'bar'); +   * ``` +   * @name .define +   * @param {String} `key` propery name +   * @param {any} `val` property value +   * @return {Object} Returns the Compiler instance for chaining. +   * @api public +   */ + +  define: function(key, val) { +    define(this, key, val); +    return this; +  }, + +  /** +   * Emit `node.val` +   */ + +  emit: function(str, node) { +    this.output += str; +    return str; +  }, + +  /** +   * Add a compiler `fn` with the given `name` +   */ + +  set: function(name, fn) { +    this.compilers[name] = fn; +    return this; +  }, + +  /** +   * Get compiler `name`. +   */ + +  get: function(name) { +    return this.compilers[name]; +  }, + +  /** +   * Get the previous AST node. +   */ + +  prev: function(n) { +    return this.ast.nodes[this.idx - (n || 1)] || { type: 'bos', val: '' }; +  }, + +  /** +   * Get the next AST node. +   */ + +  next: function(n) { +    return this.ast.nodes[this.idx + (n || 1)] || { type: 'eos', val: '' }; +  }, + +  /** +   * Visit `node`. +   */ + +  visit: function(node, nodes, i) { +    var fn = this.compilers[node.type]; +    this.idx = i; + +    if (typeof fn !== 'function') { +      throw this.error('compiler "' + node.type + '" is not registered', node); +    } +    return fn.call(this, node, nodes, i); +  }, + +  /** +   * Map visit over array of `nodes`. +   */ + +  mapVisit: function(nodes) { +    if (!Array.isArray(nodes)) { +      throw new TypeError('expected an array'); +    } +    var len = nodes.length; +    var idx = -1; +    while (++idx < len) { +      this.visit(nodes[idx], nodes, idx); +    } +    return this; +  }, + +  /** +   * Compile `ast`. +   */ + +  compile: function(ast, options) { +    var opts = utils.extend({}, this.options, options); +    this.ast = ast; +    this.parsingErrors = this.ast.errors; +    this.output = ''; + +    // source map support +    if (opts.sourcemap) { +      var sourcemaps = require('./source-maps'); +      sourcemaps(this); +      this.mapVisit(this.ast.nodes); +      this.applySourceMaps(); +      this.map = opts.sourcemap === 'generator' ? this.map : this.map.toJSON(); +      return this; +    } + +    this.mapVisit(this.ast.nodes); +    return this; +  } +}; + +/** + * Expose `Compiler` + */ + +module.exports = Compiler; diff --git a/node_modules/snapdragon/lib/parser.js b/node_modules/snapdragon/lib/parser.js new file mode 100644 index 0000000..a5a9b31 --- /dev/null +++ b/node_modules/snapdragon/lib/parser.js @@ -0,0 +1,533 @@ +'use strict'; + +var use = require('use'); +var util = require('util'); +var Cache = require('map-cache'); +var define = require('define-property'); +var debug = require('debug')('snapdragon:parser'); +var Position = require('./position'); +var utils = require('./utils'); + +/** + * Create a new `Parser` with the given `input` and `options`. + * @param {String} `input` + * @param {Object} `options` + * @api public + */ + +function Parser(options) { +  debug('initializing', __filename); +  this.options = utils.extend({source: 'string'}, options); +  this.init(this.options); +  use(this); +} + +/** + * Prototype methods + */ + +Parser.prototype = { +  constructor: Parser, + +  init: function(options) { +    this.orig = ''; +    this.input = ''; +    this.parsed = ''; + +    this.column = 1; +    this.line = 1; + +    this.regex = new Cache(); +    this.errors = this.errors || []; +    this.parsers = this.parsers || {}; +    this.types = this.types || []; +    this.sets = this.sets || {}; +    this.fns = this.fns || []; +    this.currentType = 'root'; + +    var pos = this.position(); +    this.bos = pos({type: 'bos', val: ''}); + +    this.ast = { +      type: 'root', +      errors: this.errors, +      nodes: [this.bos] +    }; + +    define(this.bos, 'parent', this.ast); +    this.nodes = [this.ast]; + +    this.count = 0; +    this.setCount = 0; +    this.stack = []; +  }, + +  /** +   * Throw a formatted error with the cursor column and `msg`. +   * @param {String} `msg` Message to use in the Error. +   */ + +  error: function(msg, node) { +    var pos = node.position || {start: {column: 0, line: 0}}; +    var line = pos.start.line; +    var column = pos.start.column; +    var source = this.options.source; + +    var message = source + ' <line:' + line + ' column:' + column + '>: ' + msg; +    var err = new Error(message); +    err.source = source; +    err.reason = msg; +    err.pos = pos; + +    if (this.options.silent) { +      this.errors.push(err); +    } else { +      throw err; +    } +  }, + +  /** +   * Define a non-enumberable property on the `Parser` instance. +   * +   * ```js +   * parser.define('foo', 'bar'); +   * ``` +   * @name .define +   * @param {String} `key` propery name +   * @param {any} `val` property value +   * @return {Object} Returns the Parser instance for chaining. +   * @api public +   */ + +  define: function(key, val) { +    define(this, key, val); +    return this; +  }, + +  /** +   * Mark position and patch `node.position`. +   */ + +  position: function() { +    var start = { line: this.line, column: this.column }; +    var self = this; + +    return function(node) { +      define(node, 'position', new Position(start, self)); +      return node; +    }; +  }, + +  /** +   * Set parser `name` with the given `fn` +   * @param {String} `name` +   * @param {Function} `fn` +   * @api public +   */ + +  set: function(type, fn) { +    if (this.types.indexOf(type) === -1) { +      this.types.push(type); +    } +    this.parsers[type] = fn.bind(this); +    return this; +  }, + +  /** +   * Get parser `name` +   * @param {String} `name` +   * @api public +   */ + +  get: function(name) { +    return this.parsers[name]; +  }, + +  /** +   * Push a `token` onto the `type` stack. +   * +   * @param {String} `type` +   * @return {Object} `token` +   * @api public +   */ + +  push: function(type, token) { +    this.sets[type] = this.sets[type] || []; +    this.count++; +    this.stack.push(token); +    return this.sets[type].push(token); +  }, + +  /** +   * Pop a token off of the `type` stack +   * @param {String} `type` +   * @returns {Object} Returns a token +   * @api public +   */ + +  pop: function(type) { +    this.sets[type] = this.sets[type] || []; +    this.count--; +    this.stack.pop(); +    return this.sets[type].pop(); +  }, + +  /** +   * Return true if inside a `stack` node. Types are `braces`, `parens` or `brackets`. +   * +   * @param {String} `type` +   * @return {Boolean} +   * @api public +   */ + +  isInside: function(type) { +    this.sets[type] = this.sets[type] || []; +    return this.sets[type].length > 0; +  }, + +  /** +   * Return true if `node` is the given `type`. +   * +   * ```js +   * parser.isType(node, 'brace'); +   * ``` +   * @param {Object} `node` +   * @param {String} `type` +   * @return {Boolean} +   * @api public +   */ + +  isType: function(node, type) { +    return node && node.type === type; +  }, + +  /** +   * Get the previous AST node +   * @return {Object} +   */ + +  prev: function(n) { +    return this.stack.length > 0 +      ? utils.last(this.stack, n) +      : utils.last(this.nodes, n); +  }, + +  /** +   * Update line and column based on `str`. +   */ + +  consume: function(len) { +    this.input = this.input.substr(len); +  }, + +  /** +   * Update column based on `str`. +   */ + +  updatePosition: function(str, len) { +    var lines = str.match(/\n/g); +    if (lines) this.line += lines.length; +    var i = str.lastIndexOf('\n'); +    this.column = ~i ? len - i : this.column + len; +    this.parsed += str; +    this.consume(len); +  }, + +  /** +   * Match `regex`, return captures, and update the cursor position by `match[0]` length. +   * @param {RegExp} `regex` +   * @return {Object} +   */ + +  match: function(regex) { +    var m = regex.exec(this.input); +    if (m) { +      this.updatePosition(m[0], m[0].length); +      return m; +    } +  }, + +  /** +   * Capture `type` with the given regex. +   * @param {String} `type` +   * @param {RegExp} `regex` +   * @return {Function} +   */ + +  capture: function(type, regex) { +    if (typeof regex === 'function') { +      return this.set.apply(this, arguments); +    } + +    this.regex.set(type, regex); +    this.set(type, function() { +      var parsed = this.parsed; +      var pos = this.position(); +      var m = this.match(regex); +      if (!m || !m[0]) return; + +      var prev = this.prev(); +      var node = pos({ +        type: type, +        val: m[0], +        parsed: parsed, +        rest: this.input +      }); + +      if (m[1]) { +        node.inner = m[1]; +      } + +      define(node, 'inside', this.stack.length > 0); +      define(node, 'parent', prev); +      prev.nodes.push(node); +    }.bind(this)); +    return this; +  }, + +  /** +   * Create a parser with open and close for parens, +   * brackets or braces +   */ + +  capturePair: function(type, openRegex, closeRegex, fn) { +    this.sets[type] = this.sets[type] || []; + +    /** +     * Open +     */ + +    this.set(type + '.open', function() { +      var parsed = this.parsed; +      var pos = this.position(); +      var m = this.match(openRegex); +      if (!m || !m[0]) return; + +      var val = m[0]; +      this.setCount++; +      this.specialChars = true; +      var open = pos({ +        type: type + '.open', +        val: val, +        rest: this.input +      }); + +      if (typeof m[1] !== 'undefined') { +        open.inner = m[1]; +      } + +      var prev = this.prev(); +      var node = pos({ +        type: type, +        nodes: [open] +      }); + +      define(node, 'rest', this.input); +      define(node, 'parsed', parsed); +      define(node, 'prefix', m[1]); +      define(node, 'parent', prev); +      define(open, 'parent', node); + +      if (typeof fn === 'function') { +        fn.call(this, open, node); +      } + +      this.push(type, node); +      prev.nodes.push(node); +    }); + +    /** +     * Close +     */ + +    this.set(type + '.close', function() { +      var pos = this.position(); +      var m = this.match(closeRegex); +      if (!m || !m[0]) return; + +      var parent = this.pop(type); +      var node = pos({ +        type: type + '.close', +        rest: this.input, +        suffix: m[1], +        val: m[0] +      }); + +      if (!this.isType(parent, type)) { +        if (this.options.strict) { +          throw new Error('missing opening "' + type + '"'); +        } + +        this.setCount--; +        node.escaped = true; +        return node; +      } + +      if (node.suffix === '\\') { +        parent.escaped = true; +        node.escaped = true; +      } + +      parent.nodes.push(node); +      define(node, 'parent', parent); +    }); + +    return this; +  }, + +  /** +   * Capture end-of-string +   */ + +  eos: function() { +    var pos = this.position(); +    if (this.input) return; +    var prev = this.prev(); + +    while (prev.type !== 'root' && !prev.visited) { +      if (this.options.strict === true) { +        throw new SyntaxError('invalid syntax:' + util.inspect(prev, null, 2)); +      } + +      if (!hasDelims(prev)) { +        prev.parent.escaped = true; +        prev.escaped = true; +      } + +      visit(prev, function(node) { +        if (!hasDelims(node.parent)) { +          node.parent.escaped = true; +          node.escaped = true; +        } +      }); + +      prev = prev.parent; +    } + +    var tok = pos({ +      type: 'eos', +      val: this.append || '' +    }); + +    define(tok, 'parent', this.ast); +    return tok; +  }, + +  /** +   * Run parsers to advance the cursor position +   */ + +  next: function() { +    var parsed = this.parsed; +    var len = this.types.length; +    var idx = -1; +    var tok; + +    while (++idx < len) { +      if ((tok = this.parsers[this.types[idx]].call(this))) { +        define(tok, 'rest', this.input); +        define(tok, 'parsed', parsed); +        this.last = tok; +        return tok; +      } +    } +  }, + +  /** +   * Parse the given string. +   * @return {Array} +   */ + +  parse: function(input) { +    if (typeof input !== 'string') { +      throw new TypeError('expected a string'); +    } + +    this.init(this.options); +    this.orig = input; +    this.input = input; +    var self = this; + +    function parse() { +      // check input before calling `.next()` +      input = self.input; + +      // get the next AST ndoe +      var node = self.next(); +      if (node) { +        var prev = self.prev(); +        if (prev) { +          define(node, 'parent', prev); +          if (prev.nodes) { +            prev.nodes.push(node); +          } +        } + +        if (self.sets.hasOwnProperty(prev.type)) { +          self.currentType = prev.type; +        } +      } + +      // if we got here but input is not changed, throw an error +      if (self.input && input === self.input) { +        throw new Error('no parsers registered for: "' + self.input.slice(0, 5) + '"'); +      } +    } + +    while (this.input) parse(); +    if (this.stack.length && this.options.strict) { +      var node = this.stack.pop(); +      throw this.error('missing opening ' + node.type + ': "' + this.orig + '"'); +    } + +    var eos = this.eos(); +    var tok = this.prev(); +    if (tok.type !== 'eos') { +      this.ast.nodes.push(eos); +    } + +    return this.ast; +  } +}; + +/** + * Visit `node` with the given `fn` + */ + +function visit(node, fn) { +  if (!node.visited) { +    define(node, 'visited', true); +    return node.nodes ? mapVisit(node.nodes, fn) : fn(node); +  } +  return node; +} + +/** + * Map visit over array of `nodes`. + */ + +function mapVisit(nodes, fn) { +  var len = nodes.length; +  var idx = -1; +  while (++idx < len) { +    visit(nodes[idx], fn); +  } +} + +function hasOpen(node) { +  return node.nodes && node.nodes[0].type === (node.type + '.open'); +} + +function hasClose(node) { +  return node.nodes && utils.last(node.nodes).type === (node.type + '.close'); +} + +function hasDelims(node) { +  return hasOpen(node) && hasClose(node); +} + +/** + * Expose `Parser` + */ + +module.exports = Parser; diff --git a/node_modules/snapdragon/lib/position.js b/node_modules/snapdragon/lib/position.js new file mode 100644 index 0000000..c859696 --- /dev/null +++ b/node_modules/snapdragon/lib/position.js @@ -0,0 +1,14 @@ +'use strict'; + +var define = require('define-property'); + +/** + * Store position for a node + */ + +module.exports = function Position(start, parser) { +  this.start = start; +  this.end = { line: parser.line, column: parser.column }; +  define(this, 'content', parser.orig); +  define(this, 'source', parser.options.source); +}; diff --git a/node_modules/snapdragon/lib/source-maps.js b/node_modules/snapdragon/lib/source-maps.js new file mode 100644 index 0000000..d8e638b --- /dev/null +++ b/node_modules/snapdragon/lib/source-maps.js @@ -0,0 +1,145 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var define = require('define-property'); +var utils = require('./utils'); + +/** + * Expose `mixin()`. + * This code is based on `source-maps-support.js` in reworkcss/css + * https://github.com/reworkcss/css/blob/master/lib/stringify/source-map-support.js + * Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> + */ + +module.exports = mixin; + +/** + * Mixin source map support into `compiler`. + * + * @param {Object} `compiler` + * @api public + */ + +function mixin(compiler) { +  define(compiler, '_comment', compiler.comment); +  compiler.map = new utils.SourceMap.SourceMapGenerator(); +  compiler.position = { line: 1, column: 1 }; +  compiler.content = {}; +  compiler.files = {}; + +  for (var key in exports) { +    define(compiler, key, exports[key]); +  } +} + +/** + * Update position. + * + * @param {String} str + */ + +exports.updatePosition = function(str) { +  var lines = str.match(/\n/g); +  if (lines) this.position.line += lines.length; +  var i = str.lastIndexOf('\n'); +  this.position.column = ~i ? str.length - i : this.position.column + str.length; +}; + +/** + * Emit `str` with `position`. + * + * @param {String} str + * @param {Object} [pos] + * @return {String} + */ + +exports.emit = function(str, node) { +  var position = node.position || {}; +  var source = position.source; +  if (source) { +    if (position.filepath) { +      source = utils.unixify(position.filepath); +    } + +    this.map.addMapping({ +      source: source, +      generated: { +        line: this.position.line, +        column: Math.max(this.position.column - 1, 0) +      }, +      original: { +        line: position.start.line, +        column: position.start.column - 1 +      } +    }); + +    if (position.content) { +      this.addContent(source, position); +    } +    if (position.filepath) { +      this.addFile(source, position); +    } + +    this.updatePosition(str); +    this.output += str; +  } +  return str; +}; + +/** + * Adds a file to the source map output if it has not already been added + * @param {String} `file` + * @param {Object} `pos` + */ + +exports.addFile = function(file, position) { +  if (typeof position.content !== 'string') return; +  if (Object.prototype.hasOwnProperty.call(this.files, file)) return; +  this.files[file] = position.content; +}; + +/** + * Adds a content source to the source map output if it has not already been added + * @param {String} `source` + * @param {Object} `position` + */ + +exports.addContent = function(source, position) { +  if (typeof position.content !== 'string') return; +  if (Object.prototype.hasOwnProperty.call(this.content, source)) return; +  this.map.setSourceContent(source, position.content); +}; + +/** + * Applies any original source maps to the output and embeds the source file + * contents in the source map. + */ + +exports.applySourceMaps = function() { +  Object.keys(this.files).forEach(function(file) { +    var content = this.files[file]; +    this.map.setSourceContent(file, content); + +    if (this.options.inputSourcemaps === true) { +      var originalMap = utils.sourceMapResolve.resolveSync(content, file, fs.readFileSync); +      if (originalMap) { +        var map = new utils.SourceMap.SourceMapConsumer(originalMap.map); +        var relativeTo = originalMap.sourcesRelativeTo; +        this.map.applySourceMap(map, file, utils.unixify(path.dirname(relativeTo))); +      } +    } +  }, this); +}; + +/** + * Process comments, drops sourceMap comments. + * @param {Object} node + */ + +exports.comment = function(node) { +  if (/^# sourceMappingURL=/.test(node.comment)) { +    return this.emit('', node.position); +  } +  return this._comment(node); +}; diff --git a/node_modules/snapdragon/lib/utils.js b/node_modules/snapdragon/lib/utils.js new file mode 100644 index 0000000..33f07e1 --- /dev/null +++ b/node_modules/snapdragon/lib/utils.js @@ -0,0 +1,48 @@ +'use strict'; + +/** + * Module dependencies + */ + +exports.extend = require('extend-shallow'); +exports.SourceMap = require('source-map'); +exports.sourceMapResolve = require('source-map-resolve'); + +/** + * Convert backslash in the given string to forward slashes + */ + +exports.unixify = function(fp) { +  return fp.split(/\\+/).join('/'); +}; + +/** + * Return true if `val` is a non-empty string + * + * @param {String} `str` + * @return {Boolean} + */ + +exports.isString = function(str) { +  return str && typeof str === 'string'; +}; + +/** + * Cast `val` to an array + * @return {Array} + */ + +exports.arrayify = function(val) { +  if (typeof val === 'string') return [val]; +  return val ? (Array.isArray(val) ? val : [val]) : []; +}; + +/** + * Get the last `n` element from the given `array` + * @param {Array} `array` + * @return {*} + */ + +exports.last = function(arr, n) { +  return arr[arr.length - (n || 1)]; +}; | 
