Skip to content

Commit

Permalink
Merge pull request #8 from mrodrig/modernize
Browse files Browse the repository at this point in the history
Modernizing - fixing dependency vulnerabilities too
  • Loading branch information
mrodrig authored Nov 19, 2018
2 parents c0c5390 + fa77874 commit fec58cf
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 134 deletions.
34 changes: 34 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Created by .gitignore support plugin (hsz.mobi)
### Node template
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# Commenting this out is preferred by some people, see
# https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules

# Users Environment Variables
.lock-wscript

.idea

test/CSV/*
8 changes: 8 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
test/
.git*
npm-debug.log
.travis.yml
node_modules/
node_modules/*
coverage/
coverage/*
6 changes: 5 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
sudo: false
language: node_js
node_js:
- "0.10"
- "11"
- "10"
- "8"
- "6"
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Node Tag Cloud HTML Generator
# tag-cloud - Node Tag Cloud HTML Generator

**This node module will take an array of tags and counts and generate a Tag/Word Cloud.**

[![Dependencies](https://img.shields.io/david/mrodrig/tag-cloud.svg?style=flat-square)](https://www.npmjs.org/package/tag-cloud)
[![Build Status](https://travis-ci.org/mrodrig/tag-cloud.svg?branch=master)](https://travis-ci.org/mrodrig/tag-cloud)
[![bitHound Dependencies](https://www.bithound.io/github/mrodrig/tag-cloud/badges/dependencies.svg)](https://www.bithound.io/github/mrodrig/tag-cloud/master/dependencies/npm)
[![Downloads](http://img.shields.io/npm/dm/tag-cloud.svg)](https://www.npmjs.org/package/tag-cloud)
[![NPM version](https://img.shields.io/npm/v/tag-cloud.svg)](https://www.npmjs.org/package/tag-cloud)
[![bitHound Score](https://www.bithound.io/github/mrodrig/tag-cloud/badges/score.svg)](https://www.bithound.io/github/mrodrig/tag-cloud)

This node module will take an array of tags and counts and generate a Tag/Word Cloud.
[![Maintainability](https://api.codeclimate.com/v1/badges/7f915482db8fb7650731/maintainability)](https://codeclimate.com/github/mrodrig/tag-cloud/maintainability)
[![Known Vulnerabilities](https://snyk.io/test/npm/tag-cloud/badge.svg)](https://snyk.io/test/npm/tag-cloud)

## Installation

Expand All @@ -17,12 +18,12 @@ $ npm install tag-cloud
## Usage

```javascript
var tagCloud = require('tag-cloud');
let tagCloud = require('tag-cloud');
```

### API

#### tagCloud(array, callback, options)
#### `tagCloud(array, callback, options)`

* `array` - An array of JSON documents of the form {tagName: <String>, count: <Number>}
* `callback` - A function of the form `function (err, html)`; This function will receive any errors and/or the HTML generated.
Expand All @@ -44,9 +45,9 @@ var tagCloud = require('tag-cloud');

```javascript

var tagCloud = require('tag-cloud');
let tagCloud = require('tag-cloud');

var tags = [
let tags = [
{tagName: 'js', count: 5},
{tagName: 'css', count: 9},
{tagName: 'less', count: 13},
Expand All @@ -66,7 +67,7 @@ tagCloud.tagCloud(tags, function (err, data) {
randomize: false
});

var promise = require('bluebird');
let promise = require('bluebird');
promise.promisifyAll(tagCloud);

/* Option 3 */
Expand Down
107 changes: 0 additions & 107 deletions lib/tagCloud.js

This file was deleted.

16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
"author": "mrodrig",
"name": "tag-cloud",
"description": "Node Tag Cloud HTML Generator",
"version": "1.1.4",
"version": "1.2.0",
"repository": {
"type": "git",
"url": "http://github.com/mrodrig/tag-cloud.git"
},
"main": "./lib/tagCloud.js",
"main": "./src/tagCloud.js",
"scripts": {
"test": "./node_modules/.bin/mocha --reporter spec"
},
Expand All @@ -25,15 +25,15 @@
"text"
],
"dependencies": {
"underscore": "1.8.3"
"underscore": "1.9.1"
},
"devDependencies": {
"mocha": "3.3.0",
"should": "13.1.2",
"async": "2.5.0"
"mocha": "5.2.0",
"should": "13.2.3",
"async": "2.6.1"
},
"engines": {
"node": "*"
"node": ">=6"
},
"license": "MIT"
}
}
8 changes: 8 additions & 0 deletions src/defaultOptions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"randomize": true,
"classPrefix": "bucket",
"additionalAttributes": {},
"replacements": [],
"numBuckets": 10,
"htmlTag": "span"
}
108 changes: 108 additions & 0 deletions src/tagCloud.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
'use strict';

let _ = require('underscore'); // Require underscore

// Default options
let defaultOptions = require('./defaultOptions.json');

// Export the following functions that will be client accessible
module.exports = {
tagCloud: tagCloud
};

/**
* Client Accessible Tag Cloud Function (Promisifiable as of v1.0.5)
* @param array Array of documents of form {tagName: String, count: Number} which will be used to generate the cloud
* @param callback Function of (err, data) which handles the error (if any) and data returned
* @param opts Document {optional} which contains any of the options from the API doc
* @returns {*}
*/
function tagCloud(array, callback, opts) {
// If this was promisified (callback and opts are swapped) then fix the argument order.
if (_.isObject(callback) && !_.isFunction(callback)) {
let func = opts;
opts = callback;
callback = func;
}

// Merge the options into the defaults
opts = _.defaults(opts || {}, defaultOptions);
// Shuffle the elements in the array to pseudo-randomize the tagCloud ordering
let min = _.min(array, function(value) { return value.count; }).count,
max = _.max(array, function(value) { return value.count; }).count,
diff = (max - min),
// Split the number of tags into the buckets as evenly as possible
numTagsPerBucket = ((diff || 1)/(opts.numBuckets - 1));
array = _.map(array, function (tag) {
if (tag.count < 0) { return callback(new Error('All tag counts must be greater than zero.')); }
let attributes = _.defaults({
class: opts.classPrefix + determineBucket(min, numTagsPerBucket, tag.count)
}, opts.additionalAttributes);
return generateHTMLTag(opts.htmlTag, attributes, opts.replacements, tag.tagName);
});
if (opts.randomize) { array = _.shuffle(array); }
let html = array.join('');
return callback(null, html);
}

/**
* Generates an HTML String with the given data
* @param tagType String tag type (ie. div, span, etc.)
* @param attributes Document {key : value}
* @param replacements Array [{find : <String>, replace: <String>}, ...]
* @param tagText String inner text of the HTML tag
* @returns {string} HTML String value
*/
function generateHTMLTag(tagType, attributes, replacements, tagText) {
let html = '<{tag}'.replace(/{tag}/, tagType);
let keys = _.keys(attributes);

// For each additional attribute, add it into the HTML
_.each(keys, function (key) {
let value = attributes[key],
attrTag = tagText;
if (_.isObject(value)) {
// If encode is specified for this key, encode the text
attrTag = value.encode ? encodeURIComponent(tagText) : tagText;
value = value.value;
}
html += generateHTMLAttribute(key, value, attrTag, replacements);
});

html += '>{text}</{tag}>'.replace(/{text}/, tagText).replace(/{tag}/, tagType);
return html;
}

/**
* Generates html attributes
* @param key
* @param value
* @param tagText
* @param replacements
*/
function generateHTMLAttribute(key, value, tagText, replacements) {
return performReplacements(' {key}="{value}"',
[
{ find: '{key}', replace: key },
{ find: '{value}', replace: value },
{ find: '{{tag}}', replace: tagText }
].concat(replacements || []));
}

function performReplacements(str, replacements) {
_.each(replacements, function (replacementDoc) {
str = str.replace(replacementDoc.find, replacementDoc.replace);
});
return str;
}

/**
* Determines the appropriate bucket number for the tag
* @param min Number value of the minimum tag count
* @param numTagsPerBucket Number value of the number of tags per bucket
* @param count Number current tag's count value
* @returns {number} returns the bucket number for the tag
*/
function determineBucket(min, numTagsPerBucket, count) {
return Math.floor((count - min) / numTagsPerBucket);
}
Loading

0 comments on commit fec58cf

Please sign in to comment.