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

redeyed

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

redeyed - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

Changelog.md

5

package.json
{
"name": "redeyed",
"version": "0.3.0",
"version": "0.4.0",
"description": "Takes JavaScript code, along with a config and returns the original code with tokens wrapped as configured.",

@@ -8,3 +8,4 @@ "author": "Thorsten Lorenz <thlorenz@gmx.de> (thlorenz.com)",

"scripts": {
"test": "tap test/*.js"
"test": "tap test/*.js",
"demo": "cd examples/browser; open index.html"
},

@@ -11,0 +12,0 @@ "repository": {

42

README.md

@@ -7,3 +7,3 @@ # redeyed [![Build Status](https://secure.travis-ci.org/thlorenz/redeyed.png)](http://travis-ci.org/thlorenz/redeyed)

[Red Eyed Tree Frog](http://allaboutfrogs.org/info/species/redeye.html) (*Agalychnis callidryas*)
[Red Eyed Tree Frog](http://allaboutfrogs.org/info/species/redeye.html) *(Agalychnis callidryas)*

@@ -14,2 +14,7 @@ ## What?

## Where?
- server side using nodejs
- in the [browser](#browser-support)
## What for?

@@ -117,2 +122,23 @@

## Browser Support
### AMD
Ensure to include [esprima](https://github.com/ariya/esprima) as one of your dependencies
```js
define(['redeyed'], function (redeyed) {
[ .. ]
});
```
### Attached to global window object
The `redeyed {Function}` will be exposed globally as `window.redeyed` - big surprise!
```html
<script type="text/javascript" src="https://raw.github.com/ariya/esprima/master/esprima.js"></script>
<script type="text/javascript" src="path/to/redeyed.js"></script>
```
## redeyed in the wild

@@ -122,14 +148,8 @@

the terminal
- [peacock](http://thlorenz.github.com/peacock/): JavaScript syntax highlighter that generates html that is compatible
with pygments styles.
## Changelog
## Examples
### 0.3
- passing more information into {Function} config
- API change: returning {Object} with code, ast, comments and tokens attached instead of just a code {String}
- comments support
- `npm explore redeyed; npm demo` will let you try the [browser example](https://github.com/thlorenz/redeyed/tree/master/examples/browser)
### 0.2
- upgrade to Esprima 1.0.0
### 0.1
- first working version

@@ -0,226 +1,246 @@

;(function () {
'use strict';
/*jshint laxbreak: true */
/*jshint laxbreak: true, browser:true */
/*global define*/
var esprima = require('esprima')
, util = require('util')
, toString = Object.prototype.toString
var esprima
, exportFn
, toString = Object.prototype.toString
;
function inspect (obj) {
return util.inspect(obj, false, 5, true);
}
if (typeof define === 'function' && define.amd) {
// client side
// amd
define(['esprima'], function (esprima) {
return bootstrap(esprima);
});
function isString (obj) {
return toString.call(obj) == '[object String]';
}
} else if (typeof window === 'object') {
// no amd -> attach to window if it exists
// Note that this requires 'esprima' to be defined on the window, so that script has to be loaded first
window.redeyed = bootstrap(window.esprima);
function isNumber (obj) {
return toString.call(obj) == '[object Number]';
} else if (typeof module === 'object' && typeof module.exports === 'object' && typeof require === 'function') {
// server side
esprima = require('esprima');
exportFn = function (redeyed) { module.exports = redeyed; };
bootstrap(esprima, exportFn);
}
function isObject (obj) {
return toString.call(obj) == '[object Object]';
}
function bootstrap(esprima, exportFn) {
function isFunction (obj) {
return toString.call(obj) == '[object Function]';
}
function isFunction (obj) {
return toString.call(obj) === '[object Function]';
}
function surroundWith (before, after) {
return function (s) { return before + s + after; };
}
function isString (obj) {
return toString.call(obj) === '[object String]';
}
function isNonCircular(key) {
return key !== '_parent';
}
function isNumber (obj) {
return toString.call(obj) === '[object Number]';
}
function objectizeString (value) {
var vals = value.split(':');
function isObject (obj) {
return toString.call(obj) === '[object Object]';
}
if (0 === vals.length || vals.length > 2)
throw new Error(
'illegal string config: ' + value +
'\nShould be of format "before:after"'
);
function surroundWith (before, after) {
return function (s) { return before + s + after; };
}
if (vals.length === 1 || vals[1].length === 0) {
return vals.indexOf(':') < 0 ? { _before: vals[0] } : { _after: vals[0] };
} else {
return { _before: vals[0], _after: vals[1] };
function isNonCircular(key) {
return key !== '_parent';
}
}
function objectize (node) {
function objectizeString (value) {
var vals = value.split(':');
// Converts 'bef:aft' to { _before: bef, _after: aft }
// and resolves undefined before/after from parent or root
if (0 === vals.length || vals.length > 2)
throw new Error(
'illegal string config: ' + value +
'\nShould be of format "before:after"'
);
function resolve (value, key) {
// resolve before/after from root or parent if it isn't present on the current node
if (!value._parent) return undefined;
// Immediate parent
if (value._parent._default && value._parent._default[key]) return value._parent._default[key];
// Root
var root = value._parent._parent;
if (!root) return undefined;
return root._default ? root._default[key] : undefined;
if (vals.length === 1 || vals[1].length === 0) {
return vals.indexOf(':') < 0 ? { _before: vals[0] } : { _after: vals[0] };
} else {
return { _before: vals[0], _after: vals[1] };
}
}
function process (key) {
var value = node[key];
function objectize (node) {
if (!value) return;
if (isFunction(value)) return;
// Converts 'bef:aft' to { _before: bef, _after: aft }
// and resolves undefined before/after from parent or root
// normalize all strings to objects
if (isString(value)) {
node[key] = value = objectizeString(value);
}
value._parent = node;
if (isObject(value)) {
if (!value._before && !value._after) return objectize (value);
// resolve missing _before or _after from parent(s)
// in case we only have either one on this node
value._before = value._before || resolve(value, '_before');
value._after = value._after || resolve(value, '_after');
function resolve (value, key) {
// resolve before/after from root or parent if it isn't present on the current node
if (!value._parent) return undefined;
return;
}
// Immediate parent
if (value._parent._default && value._parent._default[key]) return value._parent._default[key];
throw new Error('nodes need to be either {String}, {Object} or {Function}.' + value + ' is neither.');
}
// Root
var root = value._parent._parent;
if (!root) return undefined;
// Process _default ones first so children can resolve missing before/after from them
if (node._default) process('_default');
return root._default ? root._default[key] : undefined;
}
Object.keys(node)
.filter(function (key) {
return isNonCircular(key)
&& node.hasOwnProperty(key)
&& key !== '_before'
&& key !== '_after'
&& key !== '_default';
})
.forEach(process);
}
function functionize (node) {
Object.keys(node)
.filter(function (key) {
return isNonCircular(key) && node.hasOwnProperty(key);
})
.forEach(function (key) {
function process (key) {
var value = node[key];
if (!value) return;
if (isFunction(value)) return;
// normalize all strings to objects
if (isString(value)) {
node[key] = value = objectizeString(value);
}
value._parent = node;
if (isObject(value)) {
if (!value._before && !value._after) return objectize (value);
if (!value._before && !value._after) return functionize(value);
// resolve missing _before or _after from parent(s)
// in case we only have either one on this node
value._before = value._before || resolve(value, '_before');
value._after = value._after || resolve(value, '_after');
return;
}
// at this point before/after were "inherited" from the parent or root
// (see objectize)
var before = value._before || '';
var after = value._after || '';
throw new Error('nodes need to be either {String}, {Object} or {Function}.' + value + ' is neither.');
}
return node[key] = surroundWith (before, after);
}
});
}
// Process _default ones first so children can resolve missing before/after from them
if (node._default) process('_default');
function normalize (root) {
objectize(root);
functionize(root);
}
Object.keys(node)
.filter(function (key) {
return isNonCircular(key)
&& node.hasOwnProperty(key)
&& key !== '_before'
&& key !== '_after'
&& key !== '_default';
})
.forEach(process);
}
function mergeTokensAndComments(tokens, comments) {
var all = {};
function functionize (node) {
Object.keys(node)
.filter(function (key) {
return isNonCircular(key) && node.hasOwnProperty(key);
})
.forEach(function (key) {
var value = node[key];
function addToAllByRangeStart(t) { all[ t.range[0] ] = t; }
if (isFunction(value)) return;
tokens.forEach(addToAllByRangeStart);
comments.forEach(addToAllByRangeStart);
if (isObject(value)) {
// keys are sorted automatically
return Object.keys(all)
.map(function (k) { return all[k]; });
}
if (!value._before && !value._after) return functionize(value);
function redeyed (code, config, opts) {
opts = opts || {};
// at this point before/after were "inherited" from the parent or root
// (see objectize)
var before = value._before || '';
var after = value._after || '';
// remove shebang
code = code.replace(/^\#\!.*/, '');
return node[key] = surroundWith (before, after);
}
});
}
var ast = esprima.parse(code, { tokens: true, comment: true, range: true, tolerant: true })
, tokens = ast.tokens
, comments = ast.comments
, lastSplitEnd = 0
, splits = []
, transformedCode
, all
;
function normalize (root) {
objectize(root);
functionize(root);
}
// console.log(inspect(tokens));
function mergeTokensAndComments(tokens, comments) {
var all = {};
normalize(config);
function addToAllByRangeStart(t) { all[ t.range[0] ] = t; }
function addSplit (start, end, surround, tokenIdx, tokens) {
if (start >= end) return;
if (surround)
splits.push(surround(code.slice(start, end), tokenIdx, tokens));
else
splits.push(code.slice(start, end));
tokens.forEach(addToAllByRangeStart);
comments.forEach(addToAllByRangeStart);
lastSplitEnd = end;
// keys are sorted automatically
return Object.keys(all)
.map(function (k) { return all[k]; });
}
all = mergeTokensAndComments(tokens, comments);
for (var tokenIdx = 0; tokenIdx < all.length; tokenIdx++) {
var token = all[tokenIdx]
, surroundForType = config[token.type]
, surround
, start
, end;
// At least the type (e.g., 'Keyword') needs to be specified for the token to be surrounded
if (surroundForType) {
function redeyed (code, config, opts) {
opts = opts || {};
// root defaults are only taken into account while resolving before/after otherwise
// a root default would apply to everything, even if no type default was specified
surround = surroundForType
&& surroundForType.hasOwnProperty(token.value)
&& surroundForType[token.value]
&& isFunction(surroundForType[token.value])
? surroundForType[token.value]
: surroundForType._default;
// remove shebang
code = code.replace(/^\#\!.*/, '');
start = token.range[0];
end = token.range[1];
var ast = esprima.parse(code, { tokens: true, comment: true, range: true, tolerant: true })
, tokens = ast.tokens
, comments = ast.comments
, lastSplitEnd = 0
, splits = []
, transformedCode
, all
;
addSplit(lastSplitEnd, start);
addSplit(start, end, surround, tokenIdx, all);
normalize(config);
function addSplit (start, end, surround, tokenIdx, tokens) {
if (start >= end) return;
if (surround)
splits.push(surround(code.slice(start, end), tokenIdx, tokens));
else
splits.push(code.slice(start, end));
lastSplitEnd = end;
}
}
if (lastSplitEnd < code.length) {
addSplit(lastSplitEnd, code.length);
all = mergeTokensAndComments(tokens, comments);
for (var tokenIdx = 0; tokenIdx < all.length; tokenIdx++) {
var token = all[tokenIdx]
, surroundForType = config[token.type]
, surround
, start
, end;
// At least the type (e.g., 'Keyword') needs to be specified for the token to be surrounded
if (surroundForType) {
// root defaults are only taken into account while resolving before/after otherwise
// a root default would apply to everything, even if no type default was specified
surround = surroundForType
&& surroundForType.hasOwnProperty(token.value)
&& surroundForType[token.value]
&& isFunction(surroundForType[token.value])
? surroundForType[token.value]
: surroundForType._default;
start = token.range[0];
end = token.range[1];
addSplit(lastSplitEnd, start);
addSplit(start, end, surround, tokenIdx, all);
}
}
if (lastSplitEnd < code.length) {
addSplit(lastSplitEnd, code.length);
}
transformedCode = opts.nojoin ? undefined : splits.join('');
return {
ast : ast
, tokens : tokens
, comments : comments
, splits : splits
, code : transformedCode
};
}
transformedCode = opts.nojoin ? undefined : splits.join('');
return {
ast : ast
, tokens : tokens
, comments : comments
, splits : splits
, code : transformedCode
};
return exportFn ? exportFn(redeyed) : redeyed;
}
module.exports = redeyed;
})();
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