Socket
Socket
Sign inDemoInstall

dss

Package Overview
Dependencies
0
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.0 to 1.0.1

673

dss.js

@@ -1,21 +0,1 @@

/**
* Command Line Tool for _dss (Documented Style Sheets)
* @author Darcy Clarke
* @version 0.0.1
*
* Dual licensed under the MIT and GPL licenses.
*
* This library contains a Node.js port of the KSS
* Ruby library. All the JavaScript code, accept where
* explicitly noted, was written by Darcy Clarke.
*
* Based on KSS: https://github.com/kneath/kss
* @author Kyle Neath
*/
// Include dependancies
var mustache = require('mustache');
var fs = require('fs');
var path = require('path');
// DSS Object

@@ -27,28 +7,27 @@ var dss = (function(){

_dss.queue = {};
_dss.variables = {};
// Default detect function
_dss.detect = function(){
return true;
};
_dss.publish = function(topic, args){
_dss.queue[topic] && _dss.queue[topic].forEach(function(callback){
callback.apply(_dss, args || []);
});
/*
* Modify detector method
*
* @param (Function) The callback to be used to detect variables
*/
_dss.detector = function(callback){
_dss.detect = callback;
};
_dss.subscribe = function(topic, callback){
if(!_dss.queue[topic])
_dss.queue[topic] = [];
_dss.queue[topic].push(callback);
return [topic, callback];
};
_dss.unsubscribe = function(handle){
var t = handle[0];
_dss.queue[t] && _dss.queue[t].forEach(function(idx){
if(this == handle[1])
_dss.queue[t].splice(idx, 1);
});
};
_dss.describe = function(name, callback){
_dss.variables[name] = callback;
// Store parsers
_dss.parsers = {};
/*
* Add a parser for a specific variable
*
* @param (String) The name of the variable
* @param (Function) The callback to be executed at parse time
*/
_dss.parser = function(name, callback){
_dss.parsers[name] = callback;
};

@@ -72,135 +51,178 @@

/*
* Get last item in array
* Check if object is an array
*
* @param (Array) The array to use
* @return (Object) The last item in the array
* @param (Object) The object to check
* @return (Boolean) The result of the test
*/
_dss.last = function(arr){
return arr[arr.length - 1] || [];
_dss.isArray = function(obj){
return toString.call(obj) == '[object Array]';
};
/*
* Check if object is an array
* Check the size of an object
*
* @param (Object) The object to check
* @return (Boolean) The result of the test
*/
_dss.isArray = function(obj){
return toString.call(obj) == '[object Array]';
*/
_dss.size = function(obj){
var size = 0;
for(var key in obj){
if(Object.prototype.hasOwnProperty.call(obj, key))
size++;
}
return size;
};
/*
* Squeeze unnecessary extra characters/string
* Iterate over an object
*
* @param (String) The string to be squeeze
* @param (String) The string to be matched
* @return (String) The modified string
* @param (Object) The object to iterate over
* @param (Function) Callback function to use when iterating
* @param (Object) Optional context to pass to iterator
*/
_dss.squeeze = function(str, def){
return str.replace(/\s{2,}/g, def);
_dss.each = function(obj, iterator, context){
if(obj == null) return;
if(obj.length === +obj.length){
for(var i = 0, l = obj.length; i < l; i++){
if(iterator.call(context, obj[i], i, obj) === {}) return;
}
} else {
for(var key in obj){
if(_.has(obj, key)){
if(iterator.call(context, obj[key], key, obj) === {}) return;
}
}
}
};
/*
* Walks the directory structure looking for CSS files
* Extend an object
*
* @param (String) The directory to crawl
* @param (Function) The callback function to be executed when done
* @param (Object) The object to extend
*/
_dss.walker = function(dir, callback) {
var results = [];
fs.readdir(dir, function(err, list) {
if (err) return callback(err);
var pending = list.length;
if (!pending) return callback(null, results);
list.forEach(function(file) {
file = dir + '/' + file;
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
_dss.walker(file, function(err, res) {
results = results.concat(res);
if (!--pending) callback(null, results);
});
} else {
var ext = file.substr((file.lastIndexOf('.')+1), file.length);
if(ext === 'css' || ext === 'sass' || ext === 'less' || ext === 'scss')
results.push(file);
if (!--pending) callback(null, results);
}
});
});
_dss.extend = function(obj){
_dss.each(Array.prototype.slice.call(arguments, 1), function(source){
if(source){
for(var prop in source){
obj[prop] = source[prop];
}
}
});
return obj;
};
/*
* Recursively create directories
* Squeeze unnecessary extra characters/string
*
* @param (String) path of the directory to create
* @param (Number) chmod mode to set the directories at
* @param (Function) The callback function to be executed when complete
* @param (Number) Current position in the split path array
* @param (String) The string to be squeeze
* @param (String) The string to be matched
* @return (String) The modified string
*/
_dss.mkdir = function(path, mode, callback, position) {
mode = mode || 0777;
position = position || 0;
parts = require('path').normalize(path).split('/');
if(position >= parts.length){
if (callback) {
return callback();
} else {
return true;
}
}
var directory = parts.slice(0, position + 1).join('/');
fs.stat(directory, function(err) {
if (err === null) {
_dss.mkdir(path, mode, callback, position + 1);
} else {
fs.mkdir(directory, mode, function (err) {
if (err) {
if (callback) {
return callback(err);
} else {
throw err;
}
} else {
_dss.mkdir(path, mode, callback, position + 1);
}
})
}
});
_dss.squeeze = function(str, def){
return str.replace(/\s{2,}/g, def);
};
/*
* Create a file
*
* @param (String) The path to the file to create
* @param (String) The contents to write to the file
* @param (Function) The callback function when done creation
* Normalizes the comment block to ignore any consistent preceding
* whitespace. Consistent means the same amount of whitespace on every line
* of the comment block. Also strips any whitespace at the start and end of
* the whole block.
*
* @param (String) Text block
* @return (String) A cleaned up text block
*/
_dss.writeFile = function(path, contents, callback){
var directories = path.split('/');
directories.pop();
_dss.mkdir(directories.join('/'), 0777, function(){
fs.writeFile(path, contents, callback);
});
_dss.normalize = function(text_block){
// Strip out any preceding [whitespace]* that occur on every line. Not
// the smartest, but I wonder if I care.
text_block = text_block.replace(/^(\s*\*+)/, '');
// Strip consistent indenting by measuring first line's whitespace
var indent_size = false;
var unindented = (function(lines){
return lines.map(function(line){
var preceding_whitespace = line.match(/^\s*/)[0].length;
if(!indent_size)
indent_size = preceding_whitespace;
if(line == ''){
return '';
} else if(indent_size <= preceding_whitespace && indent_size > 0){
return line.slice(indent_size, (line.length - 1));
} else {
return line;
}
}).join("\n");
})(text_block.split("\n"));
return _dss.trim(text_block);
};
/*
* Takes and file path of a text file and extracts comments from it.
* Takes a file and extracts comments from it.
*
* @param (String) path to file
* @param (Object) options
* @param (Function) callback
*/
_dss.parser = (function(){
_dss.parse = function(lines, options, callback){
var _this = function(file_path, relative, options){
this.options = (options) ? options : {};
this.options.preserve_whitespace = !!(this.options.preserve_whitespace);
this._file = file_path;
this._relative = relative;
this._blocks = [];
this._parsed = false;
// Options
options = (options) ? options : {};
options.preserve_whitespace = !!(options.preserve_whitespace);
// Setup
var _this = this,
current_block = '',
inside_single_line_block = false,
inside_multi_line_block = false,
last_line = '',
start = "{start}",
end = "{/end}",
_parsed = false,
_blocks = [],
parsed = '',
blocks = [],
temp = {},
lineNum = 0;
/*
* Parses line
*
* @param (Num) the line number
* @param (Num) number of lines
* @param (String) line to parse/check
* @return (Boolean) result of parsing
*/
var parser = function(temp, line, block, file){
var indexer = function(str, find){
return (str.indexOf(find) > 0) ? str.indexOf(find) : false;
},
parts = line.replace(/.*@/, ''),
i = indexer(parts, ' ') || indexer(parts, '\n') || indexer(parts, '\r') || parts.length,
name = _dss.trim(parts.substr(0, i)),
description = _dss.trim(parts.substr(i)),
variable = _dss.parsers[name],
index = block.indexOf(line);
line = {};
line[name] = (variable) ? variable.apply(null, [index, description, block, file]) : '';
if(temp[name]){
if(!_dss.isArray(temp[name]))
temp[name] = [ temp[name] ];
temp[name].push(line[name]);
} else {
temp = _dss.extend(temp, line);
}
return temp;
};
/*
* Comment block
*/
var block = function(){
this._raw = (comment_text) ? comment_text : '';
this._filename = filename;
};
/*
* Check for single-line comment

@@ -211,3 +233,3 @@ *

*/
_this.prototype.single_line_comment = function(line){
var single_line_comment = function(line){
return !!line.match(/^\s*\/\//);

@@ -222,3 +244,3 @@ };

*/
_this.prototype.start_multi_line_comment = function(line){
var start_multi_line_comment = function(line){
return !!line.match(/^\s*\/\*/);

@@ -233,4 +255,4 @@ };

*/
_this.prototype.end_multi_line_comment = function(line){
if(this.single_line_comment(line))
var end_multi_line_comment = function(line){
if(single_line_comment(line))
return false;

@@ -246,7 +268,7 @@ return !!line.match(/.*\*\//);

*/
_this.prototype.parse_single_line = function(line){
var parse_single_line = function(line){
return line.replace(/\s*\/\//, '');
};
/*
/*
* Remove comment identifiers for multi-line comments.

@@ -257,3 +279,3 @@ *

*/
_this.prototype.parse_multi_line = function(line){
var parse_multi_line = function(line){
var cleaned = line.replace(/\s*\/\*/, '');

@@ -263,310 +285,76 @@ return cleaned.replace(/\*\//, '');

/*
* The different sections of parsed comment text. A section is
* either a multi-line comment block's content, or consecutive lines of
* single-line comments.
*
* @return (Array) The array of parsed lines/blocks
*/
_this.prototype.blocks = function(callback){
return this._parsed ? this._blocks : this.parse_blocks(callback);
};
lines = lines + '';
lines.split(/\n/).forEach(function(line){
/*
* Parse the file for comment blocks and populate them into this._blocks.
*
* @return (Array) The array of blocks
*/
_this.prototype.parse_blocks = function(callback){
var current_block = '',
inside_single_line_block = false,
inside_multi_line_block = false,
parsed = '',
_that = this,
start = "{start}",
end = "{/end}",
blocks = [];
lineNum = lineNum + 1;
line = line + '';
fs.readFile(this._file, function(err, lines){
var lineNum = 0;
if(err){
console.error("× Build error: [parse_blocks] %s", err);
process.exit(1);
// Parse Single line comment
if(single_line_comment(line)){
parsed = parse_single_line(line);
if(inside_single_line_block){
current_block += '\n' + parsed;
} else {
current_block = parsed;
inside_single_line_block = true;
}
}
lines = lines + '';
lines.split(/\n/).forEach(function(line){
lineNum = lineNum + 1;
line = line + '';
// Parse Single line comment
if(_that.single_line_comment(line)){
parsed = _that.parse_single_line(line);
if(inside_single_line_block){
current_block += start + parsed + end;
} else {
current_block = parsed;
inside_single_line_block = true;
}
}
// Parse multi-line comments
if(_that.start_multi_line_comment(line)){
current_block += start;
}
if(_that.start_multi_line_comment(line) || inside_multi_line_block){
parsed = _that.parse_multi_line(line);
if(inside_multi_line_block){
current_block += parsed;
} else {
current_block += parsed;
inside_multi_line_block = true;
}
}
// End a multi-line block
if(_that.end_multi_line_comment(line)){
inside_multi_line_block = false;
current_block += end;
}
// Store current block if done
if(!_that.single_line_comment(line) || !inside_multi_line_block){
if(current_block){
_that.normalize(current_block);
_that._blocks.push(_that.normalize(current_block));
}
inside_single_line_block = false;
current_block = '';
}
});
_that._parsed = true;
var x = 0, length = _that._blocks.length;
_that._blocks.forEach(function(block){
if(_that.dss_block(block)){
var parts = block.replace(/.*@/, ''),
i = parts.indexOf(' '),
name = _dss.trim(parts.substr(0, i)),
description = _dss.trim(parts.substr(i)),
variable = _dss.variables[name];
block = {};
block[name] = (variable) ? variable.apply(_that, [ lineNum, description, lines ] ) : '';
blocks.push( block );
}
x++;
if(x >= length){
delete _that.options;
callback({ file: _that._relative, blocks: blocks });
}
});
});
};
/*
* Normalizes the comment block to ignore any consistent preceding
* whitespace. Consistent means the same amount of whitespace on every line
* of the comment block. Also strips any whitespace at the start and end of
* the whole block.
*
* @param (String) Text block
* @return (String) A cleaned up text block
*/
_this.prototype.normalize = function(text_block){
if(this.options.preserve_whitespace)
return text_block;
// Strip out any preceding [whitespace]* that occur on every line. Not
// the smartest, but I wonder if I care.
text_block = text_block.replace(/^(\s*\*+)/, '');
// Strip consistent indenting by measuring first line's whitespace
var indent_size = false;
var unindented = (function(lines){
return lines.map(function(line){
var preceding_whitespace = line.match(/^\s*/)[0].length;
if(!indent_size)
indent_size = preceding_whitespace;
if(line == ''){
return '';
} else if(indent_size <= preceding_whitespace && indent_size > 0){
return line.slice(indent_size, (line.length - 1));
} else {
return line;
}
}).join("\n");
})(text_block.split("\n"));
return _dss.trim(text_block);
};
/*
* Takes a block and checks if it is a DSS block
*
* @param (String) Cleaned up comment
* @return (Boolean) Result of conformity check
*/
_this.prototype.dss_block = function(cleaned_comment){
if(typeof cleaned_comment !== 'string')
return false;
var possible_reference = cleaned_comment.split("\n\n").pop();
return possible_reference.match(/.*@/);
};
// Return function
return _this;
})();
/*
* Comment Block
*/
_dss.block = (function(){
var _this = function(comment_text, filename){
this._raw = (comment_text) ? comment_text : '';
this._filename = filename;
};
// The states section of a styleguide comment block.
_this.prototype.states = function(){
var last_indent = 0,
states = [];
this.states.split("\n").map(function(){
var line = this,
next = (_dss.trim(line) === ''),
indent = line.match(/^\s*/)[0].length;
if(last_indent && (indent > last_indent)){
_dss.last(states).description += _dss.squeeze(line);
// Parse multi-line comments
if(start_multi_line_comment(line) || inside_multi_line_block){
parsed = parse_multi_line(line);
if(inside_multi_line_block){
current_block += '\n' + parsed;
} else {
var split = line.split(" - "),
state = split[0],
desc = split[1];
if(state && desc)
states += new _dss.state(_dss.trim(state), _dss.trim(desc));
current_block += parsed;
inside_multi_line_block = true;
}
last_indent = indent;
});
}
return states;
};
// End a multi-line block
if(end_multi_line_comment(line)){
inside_multi_line_block = false;
}
// Return function
return _this;
// Store current block if done
if(!single_line_comment(line) && !inside_multi_line_block){
if(current_block){
_blocks.push(_dss.normalize(current_block));
}
inside_single_line_block = false;
current_block = '';
last_line = '';
}
})();
});
/*
* Build
*
* @param (String) location to file
* @param (Object) options
*/
_dss.build = (function(){
// Done first pass
_parsed = true;
_this = function(location, template_dir, output_dir){
// Create new blocks with custom parsing
_blocks.forEach(function(block){
// Walk through files
_dss.walker(location, function(err, files){
// Setup
var styleguide = [],
parsing = files.length;
// Remove extra whitespace
block = block.split('\n').filter(function(line){
return (_dss.trim(_dss.normalize(line)));
}).join('\n');
// Describe to parsing name
_dss.describe('name', function(i, line, block){
return line;
});
// Split block into lines
block.split('\n').forEach(function(line){
if(_dss.detect(line))
temp = parser(temp, _dss.normalize(line), block, lines);
});
// Push to blocks if object isn't empty
if(_dss.size(temp))
blocks.push(temp);
temp = {};
// Describe to parsing description
_dss.describe('description', function(i, line, block){
return line;
});
// Describe parsing state
_dss.describe('state', function(i, line, block){
var state = line.split('-');
return {
name: (state[0]) ? _dss.trim(state[0].replace('.', ' ').replace(':', ' pseudo-class-')) : '',
description: (state[1]) ? _dss.trim(state[1]) : ''
};
});
// Describe parsing markup
_dss.describe('markup', function(i, line, block){
return block.splice(i, block.length).join('');
});
// Subscribe to parsing comlete
_dss.subscribe('parsing:complete', function(){
console.log('✓ Styleguide Object: ', styleguide);
});
// Setup output directories
template_dir = template_dir || '../template';
output_dir = output_dir || 'styleguide';
// Setup output template and file
var template = template_dir + '/default.mustache',
output = output_dir + '/index.html';
fs.readFile(template, function(err, html){
// Check for build error
if(err){
console.error('× Build error: [readFile] %s', err);
process.exit(1);
} else {
// Execute callback with filename and blocks
callback({ blocks: blocks });
// Create HTML ouput
html = mustache.render((html + ''), styleguide);
};
// Render file
_dss.writeFile(output, html, function(err){
if(err){
console.error('× Build error: [writeFile] %s', err);
process.exit(1);
} else {
console.log('✓ Build complete');
}
});
}
});
});
// Parse
files.map(function(filename){
console.log('• ' + path.relative(location, filename));
var parser = new _dss.parser(filename, path.relative(location, filename));
parser.parse_blocks(function(parsed){
styleguide.push(parsed);
if(parsing > 1){
parsing = parsing - 1;
} else {
_dss.publish('parsing:complete');
}
});
});
});
};
// Return function
return _this;
})();
// Return function

@@ -577,5 +365,5 @@ return _dss;

// Export for Require.js and other AMD
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
// Module exports
if(typeof exports !== 'undefined'){
if(typeof module !== 'undefined' && module.exports){
exports = module.exports = dss;

@@ -588,6 +376,7 @@ }

if (typeof define === 'function' && define.amd) {
define(function(require) {
// AMD definition
if (typeof define === 'function' && define.amd){
define(function(require){
return dss;
});
}
}
{
"name": "dss",
"description": "Documented Style Sheets",
"version": "1.0.0",
"homepage": "https://github.com/darcyclarke/DSS",
"version": "1.0.1",
"homepage": "https://github.com/darcyclarke/dss",
"author": {

@@ -13,6 +13,6 @@ "name": "darcyclarke",

"type": "git",
"url": "https://github.com/darcyclarke/DSS"
"url": "https://github.com/darcyclarke/dss"
},
"bugs": {
"url": "https://github.com/darcyclarke/DSS/issues"
"url": "https://github.com/darcyclarke/dss/issues"
},

@@ -22,19 +22,21 @@ "licenses": [

"type": "MIT",
"url": "https://github.com/darcyclarke/DSS/blob/master/LICENSE-MIT"
"url": "https://github.com/darcyclarke/dss/blob/master/LICENSE-MIT"
}
],
"main": "Gruntfile.js",
"main": "dss.js",
"engines": {
"node": ">= 0.8.0"
},
"devDependencies": {
"grunt": "~0.4.0",
"mustache": "0.7.0"
"scripts": {
},
"peerDependencies": {
"grunt": "~0.4.0"
},
"dependencies": {},
"devDependencies": {},
"peerDependencies": {},
"keywords": [
"gruntplugin","css","dss","styles","docs","documentation","cli"
"css",
"dss",
"styles",
"docs",
"documentation"
]
}
}

@@ -1,7 +0,6 @@

DSS
===
# DSS
**@version 1.0**
**@logo [DSS](http://f.cl.ly/items/1J353X3U172A1u3r2K3b/dss-logo.png)**
**DSS**, Documented Style Sheets, is a [Grunt](http://grunt.js.com) plugin that exposes a [KSS](https://github.com/kneath/kss) style of comment blocking and parser of CSS, LESS, SASS and SCSS code for UI documentation generation.
**DSS**, Documented Style Sheets, is a parser and style guide that creates UI documentation objects from properly commented CSS, LESS, STYLUS, SASS and SCSS files.

@@ -24,42 +23,52 @@ ### Example Comment Block

````
#### or
## Getting Started
This plugin requires Grunt `~0.4.0`
```scss
//
// @name Button
// @description Your standard form button.
//
// @state :hover - Highlights when hovering.
// @state :disabled - Dims the button when disabled.
// @state .primary - Indicates button is the primary action.
// @state .smaller - A smaller button
//
// @markup
// <button>This is a button</button>
//
````
If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
### Example Generated Object
```shell
npm install DSS --save-dev
```
One the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
```js
grunt.loadNpmTasks('DSS');
```
## The "DSS" task
### Overview
In your project's Gruntfile, add a section named `DSS` to the data object passed into `grunt.initConfig()`.
```js
grunt.initConfig({
DSS: {
options: {
// Task-specific options go here.
```javascript
{
"name": "Button",
"description": "Your standard form button.",
"state": [
{
"name": ":hover",
"escaped": "pseudo-class-hover",
"description": "Highlights when hovering."
},
your_target: {
// Target-specific file lists and/or options go here.
{
"name": ":disabled",
"escaped": "pseudo-class-disabled",
"description": "Dims the button when disabled."
},
},
})
```
### Options
#### options.template
Type: `String`
Default value: `default`
A relative path to a `mustache` template to be used instead of the default
{
"name": ".primary",
"escaped": "primary",
"description": "Indicates button is the primary action."
},
{
"name": ".smaller",
"escaped": "smaller",
"description": "A smaller button"
}
],
"markup": {
"example": "<button>This is a button</button>",
"escaped": "&lt;button&gt;This is a button&lt;/button&gt;"
}
}
````

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc