Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

caesar-parser

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

caesar-parser - npm Package Compare versions

Comparing version 0.0.1 to 0.1.0

lib/Context.js

110

lib/JsonParser.js

@@ -9,3 +9,3 @@ 'use strict';

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
var _get = function get(_x2, _x3, _x4) { var _again = true; _function: while (_again) { var object = _x2, property = _x3, receiver = _x4; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x2 = parent; _x3 = property; _x4 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

@@ -47,15 +47,2 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

_createClass(JsonParser, [{
key: 'parse',
value: function parse() {
_Parser3['default'].prototype.parse.apply(this, arguments);
if (this.ctx.value !== undefined) {
this._res = this.ctx.value;
}
return this._res;
}
/**
* @override
*/
}, {
key: 'token',

@@ -71,3 +58,55 @@ value: function token(st) {

}
/**
* @param {number} indentSize - default tabSize
* @returns {Promise}
*/
}, {
key: 'reformatCode',
value: function reformatCode(indentSize) {
var resCode = [];
indentSize = indentSize || this._tabSize;
var level = 0;
return this._iter(function (stream) {
var indentNum = stream.indentation();
var str = stream._string.slice(indentNum);
var indentStack = stream.indentStack;
if (str !== '') {
stream.readStack(indentStack, function (type, substr) {
substr = substr.trim('');
switch (type) {
case 'enter':
resCode.push(substr + '\n');
level++;
_indent();
break;
case 'outer':
level--;
resCode.push('\n');
_indent(substr);
break;
case 'space':
resCode.push(substr + ' ');
break;
case 'align':
resCode.push(substr + '\n');
_indent();
break;
default:
resCode.push(substr);
break;
}
});
}
}, { saveStyle: true }).then(function () {
return resCode.join('');
});
function _indent() {
var str = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];
resCode.push(Array(indentSize * level).fill(' ').join('') + str);
}
}
}, {
key: '_value',

@@ -79,6 +118,9 @@ value: function _value(st) {

case '{':
st.style('operator', 'enter');
return this.pushCtx(this._object, { type: 'object', value: {} });
case '[':
st.style('operator', 'enter');
return this.pushCtx(this._array, { type: 'array', value: [] });
case '"':
st.style('string');
var str = this._string(st);

@@ -88,2 +130,3 @@ this._saveValue(str);

case '-':
st.style('number');
var num = this._number(st);

@@ -94,5 +137,7 @@ this._saveValue(num);

if (ch >= '0' && ch <= '9') {
st.style('number');
var num2 = this._number(st);
this._saveValue(num2);
} else {
st.style('keyword');
var word = this._word(st);

@@ -107,8 +152,12 @@ this._saveValue(word);

var ctx = this.ctx;
if (ctx.type === 'object') {
ctx.value[ctx.key] = value;
} else if (ctx.type === 'array') {
ctx.value.push(value);
var type = ctx.get('type');
var val = ctx.get('value');
if (type === 'object') {
val = val.set(ctx.get('key'), value);
this.setCtx('value', val);
} else if (type === 'array') {
val = val.push(value);
this.setCtx('value', val);
} else {
ctx.value = value;
this.setCtx('value', value);
}

@@ -121,12 +170,16 @@ }

if (ch === '}') {
st.style('operator', 'outer');
this.popCtx();
this._saveValue(ctx.value);
this._saveValue(ctx.get('value'));
return false;
} else if (ch === '"') {
ctx.key = this._string(st);
st.style('property');
this.setCtx('key', this._string(st));
if (st.trimNext() !== ':') {
return this.error('object syntax error.', st.pos);
}
st.style('operator', 'space');
return this._value(st);
} else if (ch === ',') {
st.style('operator', 'align');
return false;

@@ -140,15 +193,17 @@ }

var ch = st.trimNext();
if (ctx.mustEatArrayItem && (ch === ']' || ch === ',')) {
if (ctx.get('mustEatArrayItem') && (ch === ']' || ch === ',')) {
return this.error('array syntax error.', st.pos);
}
if (ch === ']') {
st.style('operator', 'outer');
this.popCtx();
this._saveValue(ctx.value);
this._saveValue(ctx.get('value'));
return false;
} else if (ch === ',') {
ctx.mustEatArrayItem = true;
st.style('operator', 'align');
this.setCtx('mustEatArrayItem', true);
return false;
}
st.backUp(1);
ctx.mustEatArrayItem = false;
this.setCtx('mustEatArrayItem', false);
return this._value(st);

@@ -220,5 +275,4 @@ }

// 非数字时后退
var peek = st.peek();
if (peek && peek.trim()) {
st.backUp();
if (ch) {
st.backUp(1);
}

@@ -225,0 +279,0 @@ if (isNaN(number)) {

@@ -9,2 +9,4 @@ 'use strict';

var _get = function get(_x6, _x7, _x8) { var _again = true; _function: while (_again) { var object = _x6, property = _x7, receiver = _x8; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x6 = parent; _x7 = property; _x8 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

@@ -14,2 +16,6 @@

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var _events = require('events');
var _constants = require('./constants');

@@ -21,6 +27,8 @@

var _objectAssign = require('object-assign');
var _Context = require('./Context');
var _objectAssign2 = _interopRequireDefault(_objectAssign);
var _Context2 = _interopRequireDefault(_Context);
var _utils = require('./utils');
var _colors = require('colors');

@@ -32,32 +40,11 @@

var Context = (function () {
function Context(tokenize, data) {
_classCallCheck(this, Context);
var Parser = (function (_EventEmitter) {
_inherits(Parser, _EventEmitter);
this.pre = null;
this.tokenize = tokenize;
(0, _objectAssign2['default'])(this, data);
}
_createClass(Context, [{
key: 'push',
value: function push(tokenize, data) {
var ctx = new Context(tokenize, data);
ctx.pre = this;
return ctx;
}
}, {
key: 'pop',
value: function pop() {
return this.pre;
}
}]);
return Context;
})();
var Parser = (function () {
/**
* @param {string} code
* @param {?object} opts
* {
* tabSize: 4
* }
*/

@@ -71,8 +58,7 @@

this._code = code.split(_constants.ENDED_REG);
_get(Object.getPrototypeOf(Parser.prototype), 'constructor', this).call(this);
this._tabSize = opts.tabSize || 4;
this._res = null;
this._row = 0;
this._errorHandlers = [];
this.ctx = new Context();
this._initCode(code);
this._delayed = new _utils.Delayed();
this._readyPause = false; // 触发暂停
}

@@ -95,2 +81,10 @@

* @param {function} fn
* @param {object} opts
* {
* {number} startRow - 开始遍历的位置, 默认之前停留的时间
* {boolean} saveStyle - 是否保存样式
* {boolean} delayed - 开启延迟, 用于编辑器分段解析
* {number} delayTime - 延迟时间, 默认0
* }
* @returns {Promise}
* @private

@@ -101,7 +95,44 @@ */

value: function _iter(fn) {
this._row = 0;
while (this._row < this._code.length) {
if (fn(this._code[this._row])) break;
this._row++;
}
var _this = this;
var opts = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
this._row = opts.startRow || this._row;
var delayed = opts.delayed ? this._delayed : function (_fn) {
_fn();
};
return new Promise(function (res, rej) {
if (_this._row >= _this._code.length) {
return res(true);
}
var errorHandler = function errorHandler(error) {
_this.removeErrorHandler(errorHandler);
rej(error);
};
_this.onError(errorHandler);
var run = function run() {
if (_this._readyPause) {
_this._readyPause = false;
return;
}
var str = _this._code[_this._row];
var stream = new _StringStream2['default'](str, { tabSize: _this._tabSize, saveStyle: opts.saveStyle });
while (!stream.eol()) {
// if return true, break the parser
if (_this.token(stream)) {
_this._res = null;
return;
}
}
_this.emit('parse', fn && fn(stream, _this._row), _this._row);
_this._row++;
if (_this._row < _this._code.length) {
delayed(run, opts.delayTime);
} else {
_this.removeErrorHandler(errorHandler);
res(true);
}
};
delayed(run, opts.delayTime);
});
}

@@ -117,4 +148,2 @@

value: function error(msg, col) {
var _this = this;
var errorMsg = '';

@@ -136,16 +165,39 @@ var lines = undefined,

lines = lines.concat(afterLines);
this._errorHandlers.forEach(function (fn) {
fn.call(_this, {
message: _colors2['default'].bgBlack('\n' + lines.join('\n')),
text: msg,
row: row,
col: col
});
this.emit('error', {
message: _colors2['default'].bgBlack('\n' + lines.join('\n')),
text: msg,
row: row,
col: col
});
return true;
}
}, {
key: 'clearContext',
value: function clearContext() {
this.ctx = new _Context2['default']();
this._ctxList.length = 0;
this._row = 0;
}
}, {
key: '_initCode',
value: function _initCode(code) {
this._res = null;
this._row = 0;
this._code = code.split(_constants.ENDED_REG);
this.ctx = new _Context2['default']();
this._ctxList = [];
}
}, {
key: 'onParse',
value: function onParse(fn) {
this.on('parse', fn);
}
}, {
key: 'removeParseHandler',
value: function removeParseHandler(fn) {
this.removeListener('parse', fn);
}
/**
* @param {function} fn
* @examples
*/

@@ -155,8 +207,86 @@ }, {

value: function onError(fn) {
this._errorHandlers.push(fn);
this.on('error', fn);
}
}, {
key: 'removeErrorHandler',
value: function removeErrorHandler(fn) {
this.removeListener('error', fn);
}
/**
* @param {?string} code - 需要解析的代码, 可以为空
* @param {object} opts
* {number} startRow - 开始遍历的位置, 默认之前停留的时间
* {boolean} delayed - 开启延迟, 用于编辑器分段解析
* {number} delayTime - 延迟时间, 默认0
* @returns {Promise}
*/
}, {
key: 'highlight',
value: function highlight(code) {
var _this2 = this;
var opts = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
code && this._initCode(code);
var startRow = opts.startRow || this._row;
if (this._ctxList.length !== 0 && opts.startRow > 0) {
// 获取之前的状态
this.ctx = this._ctxList[startRow - 1] && this._ctxList[startRow - 1].context;
this._ctxList = this._ctxList.slice(0, startRow);
} else if (startRow === 0) {
this.clearContext();
}
opts.startRow = startRow;
opts.saveStyle = true;
return this._iter(function (stream) {
var ctx = {
context: _this2.ctx,
styleStack: stream.styleStack,
indentStack: stream.indentStack
};
_this2._ctxList.push(ctx);
return ctx;
}, opts).then(function () {
_this2._res = _this2.ctx.toJS();
_this2._row = 0;
return _this2._ctxList.map(function (item) {
return item.styleStack;
});
});
}
/**
* @param {number} row
* @param {object} opts
* {boolean} delayed - 开启延迟, 用于编辑器分段解析
* {number} delayTime - 延迟时间, 默认0
* @returns {Promise}
*/
}, {
key: 'highlightFrom',
value: function highlightFrom(row) {
var opts = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
opts.startRow = row;
return this.highlight(null, opts);
}
/**
* 暂停
*/
}, {
key: 'pause',
value: function pause() {
this._readyPause = true;
}
}, {
key: 'keepOn',
value: function keepOn(opts) {
return this.highlight(null, opts);
}
/**
* @param {string} code
* @returns {*} parse result
* @returns {Promise}
*/

@@ -166,16 +296,14 @@ }, {

value: function parse(code) {
var _this2 = this;
var _this3 = this;
code && (this._code = code.split(_constants.ENDED_REG));
this._iter(function (str) {
var stream = new _StringStream2['default'](str, { tabSize: _this2._tabSize });
while (!stream.eol()) {
// if return true, break the parse
if (_this2.token(stream)) {
_this2._res = null;
return true;
}
}
this.clearContext();
return this._iter(function () {
return { context: _this3.ctx };
}).then(function () {
_this3._res = _this3.ctx.toJS();
// clear ctx
_this3.clearContext();
return _this3._res;
});
return this._res;
}

@@ -195,2 +323,7 @@ }, {

}
}, {
key: 'setCtx',
value: function setCtx(key, value) {
this.ctx = this.ctx.set(key, value);
}

@@ -206,8 +339,13 @@ /**

}
}, {
key: 'row',
get: function get() {
return this._row;
}
}]);
return Parser;
})();
})(_events.EventEmitter);
exports['default'] = Parser;
module.exports = exports['default'];

@@ -19,2 +19,3 @@ 'use strict';

* stringStart: 0,
* saveStyle: false,
* tabSize: 4,

@@ -32,4 +33,7 @@ * }

this._tabSize = opts.tabSize || 4;
this._saveStyle = opts.saveStyle || false;
this._pos = 0;
this._string = string;
this._styleStack = [];
this._indentStack = [];
}

@@ -195,3 +199,43 @@

}
/**
* @param {string} name - style name, like operator variable
* @param {string} indentCode - 'enter' | 'outer' | 'space' | 'align'
*/
}, {
key: 'style',
value: function style(name, indentCode) {
if (this._saveStyle) {
this._styleStack.push(this._pos - 1, name);
indentCode && this._indentStack.push(this._pos - 1, indentCode);
}
}
}, {
key: 'readStack',
value: function readStack(stack, fn) {
var _this = this;
var pre = 0;
var substr = undefined;
stack.forEach(function (pos, key) {
if (key % 2 === 0) {
substr = _this._string.slice(pre, pos + 1);
pre = pos + 1;
} else {
fn(pos, substr);
}
});
if (pre < this._string.length - 1) fn(null, this._string.slice(pre));
}
}, {
key: 'styleStack',
get: function get() {
return this._styleStack;
}
}, {
key: 'indentStack',
get: function get() {
return this._indentStack;
}
}, {
key: 'pos',

@@ -198,0 +242,0 @@ get: function get() {

{
"name": "caesar-parser",
"version": "0.0.1",
"version": "0.1.0",
"description": "",

@@ -17,3 +17,4 @@ "main": "lib/index.js",

"build:lib": "babel src --optional es7.decorators --out-dir lib",
"build": "npm run clean && npm run build:lib"
"build": "npm run clean && npm run build:lib",
"validate": "npm ls"
},

@@ -29,2 +30,3 @@ "repository": {},

"lint",
"test",
"build"

@@ -48,4 +50,9 @@ ],

},
"engines": {
"install-node": "5.0.0"
},
"dependencies": {
"colors": "~1.1.2",
"events": "~1.1.0",
"immutable": "~3.7.5",
"object-assign": "~3.0.0",

@@ -52,0 +59,0 @@ "react": "~0.13.3"

@@ -19,12 +19,2 @@ import Parser from './Parser'

*/
parse() {
Parser.prototype.parse.apply(this, arguments)
if (this.ctx.value !== undefined) {
this._res = this.ctx.value
}
return this._res
}
/**
* @override
*/
token(st) {

@@ -39,2 +29,49 @@ if (st.eatSpace() && st.eol()) {

}
/**
* @param {number} indentSize - default tabSize
* @returns {Promise}
*/
reformatCode(indentSize) {
const resCode = []
indentSize = indentSize || this._tabSize
let level = 0
return this._iter((stream)=> {
const indentNum = stream.indentation()
const str = stream._string.slice(indentNum)
const indentStack = stream.indentStack
if (str !== '') {
stream.readStack(indentStack, (type, substr)=> {
substr = substr.trim('')
switch (type) {
case 'enter':
resCode.push(substr + '\n')
level ++
_indent()
break
case 'outer':
level --
resCode.push('\n')
_indent(substr)
break
case 'space':
resCode.push(substr + ' ')
break
case 'align':
resCode.push(substr + '\n')
_indent()
break
default:
resCode.push(substr)
break
}
})
}
}, {saveStyle: true}).then(()=> {
return resCode.join('')
})
function _indent(str = '') {
resCode.push(Array(indentSize * level).fill(' ').join('') + str)
}
}
_value(st) {

@@ -45,6 +82,9 @@ const ch = st.trimNext()

case '{':
st.style('operator', 'enter')
return this.pushCtx(this._object, {type: 'object', value: {}})
case '[':
st.style('operator', 'enter')
return this.pushCtx(this._array, {type: 'array', value: []})
case '"':
st.style('string')
const str = this._string(st)

@@ -54,2 +94,3 @@ this._saveValue(str)

case '-':
st.style('number')
const num = this._number(st)

@@ -60,5 +101,7 @@ this._saveValue(num)

if (ch >= '0' && ch <= '9') {
st.style('number')
const num2 = this._number(st)
this._saveValue(num2)
} else {
st.style('keyword')
const word = this._word(st)

@@ -71,8 +114,12 @@ this._saveValue(word)

const ctx = this.ctx
if (ctx.type === 'object') {
ctx.value[ctx.key] = value
} else if (ctx.type === 'array') {
ctx.value.push(value)
const type = ctx.get('type')
let val = ctx.get('value')
if (type === 'object') {
val = val.set(ctx.get('key'), value)
this.setCtx('value', val)
} else if (type === 'array') {
val = val.push(value)
this.setCtx('value', val)
} else {
ctx.value = value
this.setCtx('value', value)
}

@@ -83,12 +130,16 @@ }

if (ch === '}') {
st.style('operator', 'outer')
this.popCtx()
this._saveValue(ctx.value)
this._saveValue(ctx.get('value'))
return false
} else if (ch === '"') {
ctx.key = this._string(st)
st.style('property')
this.setCtx('key', this._string(st))
if (st.trimNext() !== ':') {
return this.error('object syntax error.', st.pos)
}
st.style('operator', 'space')
return this._value(st)
} else if (ch === ',') {
st.style('operator', 'align')
return false

@@ -100,15 +151,17 @@ }

const ch = st.trimNext()
if (ctx.mustEatArrayItem && (ch === ']' || ch === ',')) {
if (ctx.get('mustEatArrayItem') && (ch === ']' || ch === ',')) {
return this.error('array syntax error.', st.pos)
}
if (ch === ']') {
st.style('operator', 'outer')
this.popCtx()
this._saveValue(ctx.value)
this._saveValue(ctx.get('value'))
return false
} else if (ch === ',') {
ctx.mustEatArrayItem = true
st.style('operator', 'align')
this.setCtx('mustEatArrayItem', true)
return false
}
st.backUp(1)
ctx.mustEatArrayItem = false
this.setCtx('mustEatArrayItem', false)
return this._value(st)

@@ -174,5 +227,4 @@ }

// 非数字时后退
const peek = st.peek()
if (peek && peek.trim()) {
st.backUp()
if (ch) {
st.backUp(1)
}

@@ -179,0 +231,0 @@ if (isNaN(number)) {

@@ -0,34 +1,23 @@

import {EventEmitter} from 'events'
import {ENDED_REG} from './constants'
import StringStream from './StringStream'
import assign from 'object-assign'
import Context from './Context'
import {Delayed} from './utils'
import colors from 'colors'
const ERR_LIMIT = 3
class Context {
constructor(tokenize, data) {
this.pre = null
this.tokenize = tokenize
assign(this, data)
}
push(tokenize, data) {
const ctx = new Context(tokenize, data)
ctx.pre = this
return ctx
}
pop() {
return this.pre
}
}
class Parser {
class Parser extends EventEmitter {
/**
* @param {string} code
* @param {?object} opts
* {
* tabSize: 4
* }
*/
constructor(code = '', opts = {}) {
this._code = code.split(ENDED_REG)
super()
this._tabSize = opts.tabSize || 4
this._res = null
this._row = 0
this._errorHandlers = []
this.ctx = new Context()
this._initCode(code)
this._delayed = new Delayed
this._readyPause = false // 触发暂停
}

@@ -46,10 +35,49 @@ /**

* @param {function} fn
* @param {object} opts
* {
* {number} startRow - 开始遍历的位置, 默认之前停留的时间
* {boolean} saveStyle - 是否保存样式
* {boolean} delayed - 开启延迟, 用于编辑器分段解析
* {number} delayTime - 延迟时间, 默认0
* }
* @returns {Promise}
* @private
*/
_iter(fn) {
this._row = 0
while (this._row < this._code.length) {
if (fn(this._code[this._row])) break
this._row ++
}
_iter(fn, opts = {}) {
this._row = opts.startRow || this._row
const delayed = opts.delayed ? this._delayed : function(_fn) { _fn() }
return new Promise((res, rej)=> {
if (this._row >= this._code.length) {
return res(true)
}
const errorHandler = (error)=> {
this.removeErrorHandler(errorHandler)
rej(error)
}
this.onError(errorHandler)
const run = ()=> {
if (this._readyPause) {
this._readyPause = false
return
}
const str = this._code[this._row]
const stream = new StringStream(str, {tabSize: this._tabSize, saveStyle: opts.saveStyle})
while (!stream.eol()) {
// if return true, break the parser
if (this.token(stream)) {
this._res = null
return
}
}
this.emit('parse', fn && fn(stream, this._row), this._row)
this._row ++
if (this._row < this._code.length) {
delayed(run, opts.delayTime)
} else {
this.removeErrorHandler(errorHandler)
res(true)
}
}
delayed(run, opts.delayTime)
})
}

@@ -73,36 +101,104 @@ /**

lines = lines.concat(afterLines)
this._errorHandlers.forEach((fn)=> {
fn.call(this, {
message: colors.bgBlack('\n' + lines.join('\n')),
text: msg,
row: row,
col: col,
})
this.emit('error', {
message: colors.bgBlack('\n' + lines.join('\n')),
text: msg,
row: row,
col: col,
})
return true
}
clearContext() {
this.ctx = new Context()
this._ctxList.length = 0
this._row = 0
}
_initCode(code) {
this._res = null
this._row = 0
this._code = code.split(ENDED_REG)
this.ctx = new Context()
this._ctxList = []
}
onParse(fn) {
this.on('parse', fn)
}
removeParseHandler(fn) {
this.removeListener('parse', fn)
}
/**
* @param {function} fn
* @examples
*/
onError(fn) {
this._errorHandlers.push(fn)
this.on('error', fn)
}
removeErrorHandler(fn) {
this.removeListener('error', fn)
}
/**
* @param {?string} code - 需要解析的代码, 可以为空
* @param {object} opts
* {number} startRow - 开始遍历的位置, 默认之前停留的时间
* {boolean} delayed - 开启延迟, 用于编辑器分段解析
* {number} delayTime - 延迟时间, 默认0
* @returns {Promise}
*/
highlight(code, opts = {}) {
code && (this._initCode(code))
const startRow = opts.startRow || this._row
if (this._ctxList.length !== 0 && opts.startRow > 0) {
// 获取之前的状态
this.ctx = this._ctxList[startRow - 1] && this._ctxList[startRow - 1].context
this._ctxList = this._ctxList.slice(0, startRow)
} else if (startRow === 0) {
this.clearContext()
}
opts.startRow = startRow
opts.saveStyle = true
return this._iter((stream)=> {
const ctx = {
context: this.ctx,
styleStack: stream.styleStack,
indentStack: stream.indentStack,
}
this._ctxList.push(ctx)
return ctx
}, opts).then(()=> {
this._res = this.ctx.toJS()
this._row = 0
return this._ctxList.map((item) => item.styleStack)
})
}
/**
* @param {number} row
* @param {object} opts
* {boolean} delayed - 开启延迟, 用于编辑器分段解析
* {number} delayTime - 延迟时间, 默认0
* @returns {Promise}
*/
highlightFrom(row, opts = {}) {
opts.startRow = row
return this.highlight(null, opts)
}
/**
* 暂停
*/
pause() {
this._readyPause = true
}
keepOn(opts) {
return this.highlight(null, opts)
}
/**
* @param {string} code
* @returns {*} parse result
* @returns {Promise}
*/
parse(code) {
code && (this._code = code.split(ENDED_REG))
this._iter((str)=> {
const stream = new StringStream(str, {tabSize: this._tabSize})
while (!stream.eol()) {
// if return true, break the parse
if (this.token(stream)) {
this._res = null
return true
}
}
this.clearContext()
return this._iter(() => {return {context: this.ctx}}).then(()=> {
this._res = this.ctx.toJS()
// clear ctx
this.clearContext()
return this._res
})
return this._res
}

@@ -116,2 +212,5 @@ pushCtx() {

}
setCtx(key, value) {
this.ctx = this.ctx.set(key, value)
}
/**

@@ -124,4 +223,7 @@ * parse result

}
get row() {
return this._row
}
}
export default Parser

@@ -9,2 +9,3 @@ import {SPACE_REG} from './constants'

* stringStart: 0,
* saveStyle: false,
* tabSize: 4,

@@ -16,4 +17,7 @@ * }

this._tabSize = opts.tabSize || 4
this._saveStyle = opts.saveStyle || false
this._pos = 0
this._string = string
this._styleStack = []
this._indentStack = []
}

@@ -139,2 +143,31 @@ /**

}
/**
* @param {string} name - style name, like operator variable
* @param {string} indentCode - 'enter' | 'outer' | 'space' | 'align'
*/
style(name, indentCode) {
if (this._saveStyle) {
this._styleStack.push(this._pos - 1, name)
indentCode && this._indentStack.push(this._pos - 1, indentCode)
}
}
readStack(stack, fn) {
let pre = 0
let substr
stack.forEach((pos, key)=> {
if (key % 2 === 0) {
substr = this._string.slice(pre, pos + 1)
pre = pos + 1
} else {
fn(pos, substr)
}
})
if (pre < this._string.length - 1) fn(null, this._string.slice(pre))
}
get styleStack() {
return this._styleStack
}
get indentStack() {
return this._indentStack
}
get pos() {

@@ -141,0 +174,0 @@ return this._pos

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc