123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- 'use strict';
- var typeOf = require('kind-of');
- var define = require('define-property');
- var extend = require('extend-shallow');
- var Snapdragon = require('snapdragon');
- var compilers = require('./compilers');
- var parsers = require('./parsers');
- var utils = require('./utils');
- /**
- * Customize Snapdragon parser and renderer
- */
- function Braces(options) {
- this.options = extend({}, options);
- }
- /**
- * Initialize braces
- */
- Braces.prototype.init = function(options) {
- if (this.isInitialized) return;
- this.isInitialized = true;
- var opts = utils.createOptions({}, this.options, options);
- this.snapdragon = this.options.snapdragon || new Snapdragon(opts);
- this.compiler = this.snapdragon.compiler;
- this.parser = this.snapdragon.parser;
- compilers(this.snapdragon, opts);
- parsers(this.snapdragon, opts);
- /**
- * Call Snapdragon `.parse` method. When AST is returned, we check to
- * see if any unclosed braces are left on the stack and, if so, we iterate
- * over the stack and correct the AST so that compilers are called in the correct
- * order and unbalance braces are properly escaped.
- */
- define(this.snapdragon, 'parse', function(pattern, options) {
- var parsed = Snapdragon.prototype.parse.apply(this, arguments);
- this.parser.ast.input = pattern;
- var stack = this.parser.stack;
- while (stack.length) {
- addParent({type: 'brace.close', val: ''}, stack.pop());
- }
- function addParent(node, parent) {
- define(node, 'parent', parent);
- parent.nodes.push(node);
- }
- // add non-enumerable parser reference
- define(parsed, 'parser', this.parser);
- return parsed;
- });
- };
- /**
- * Decorate `.parse` method
- */
- Braces.prototype.parse = function(ast, options) {
- if (typeOf(ast) === 'object' && ast.nodes) return ast;
- this.init(options);
- return this.snapdragon.parse(ast, options);
- };
- /**
- * Decorate `.compile` method
- */
- Braces.prototype.compile = function(ast, options) {
- if (typeof ast === 'string') {
- ast = this.parse(ast, options);
- } else {
- this.init(options);
- }
- return this.snapdragon.compile(ast, options);
- };
- /**
- * Expand
- */
- Braces.prototype.expand = function(pattern) {
- var ast = this.parse(pattern, {expand: true});
- return this.compile(ast, {expand: true});
- };
- /**
- * Optimize
- */
- Braces.prototype.optimize = function(pattern) {
- var ast = this.parse(pattern, {optimize: true});
- return this.compile(ast, {optimize: true});
- };
- /**
- * Expose `Braces`
- */
- module.exports = Braces;
|