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": "<button>This is a button</button>" | ||
} | ||
} | ||
```` |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
0
0
74
0
13141
5
325