styledocco
Advanced tools
Comparing version 0.5.0 to 0.6.0
360
cli.js
'use strict'; | ||
var async = require('async'); | ||
var cleancss = require('clean-css'); | ||
var exec = require('child_process').exec; | ||
@@ -10,18 +11,36 @@ var findit = require('findit'); | ||
var mkdirp = require('mkdirp'); | ||
// var mincss = require('ncss'); | ||
var mincss = function(str) { return str; }; | ||
var path = require('path'); | ||
var minjs = require('uglify-js'); | ||
var uglifyjs = require('uglify-js'); | ||
var util = require('util'); | ||
var styledocco = require('./styledocco'); | ||
var version = require('./package').version; | ||
marked.setOptions({ sanitize: false, gfm: true }); | ||
// Helper functions | ||
var add = function(a, b) { return a + b; }; | ||
var readFileSync = function(file) { return fs.readFileSync(file, 'utf-8'); }; | ||
var mincss = function(css) { return cleancss.process(css); }; | ||
var minjs = uglifyjs; | ||
var pluck = function(arr, prop) { | ||
return arr.map(function(item) { return item[prop]; }); | ||
}; | ||
var flatten = function(arr) { | ||
return arr.reduce(function(tot, cur) { | ||
return tot.concat(isArray(cur) ? flatten(cur) : cur); | ||
}, []); | ||
}; | ||
var inArray = function(arr, str) { return arr.indexOf(str) !== -1; }; | ||
var isArray = function(obj) { | ||
return Object.prototype.toString.call(obj) === '[object Array]'; | ||
}; | ||
// Get a filename without the extension | ||
var baseFilename = function(str) { | ||
return path.basename(str, path.extname(str)); | ||
var baseFilename = function(str) { return path.basename(str, path.extname(str)); }; | ||
var basePathname = function(file, basePath) { | ||
return path.join( | ||
path.dirname(path.relative(basePath, file) || path.basename(basePath)), | ||
baseFilename(file) | ||
); | ||
}; | ||
@@ -38,19 +57,24 @@ | ||
// Find first file matching `re` in `dir`. | ||
var findFile = function(dir, re) { | ||
if (!fs.statSync(dir).isDirectory()) return null; | ||
var files = fs.readdirSync(dir).sort().filter(function(file) { | ||
return file.match(re); | ||
var findFile = function(dir, re, cb) { | ||
fs.stat(dir, function(err, stat) { | ||
var files = fs.readdir(dir, function(err, files) { | ||
files = files.sort().filter(function(file) { return file.match(re); }); | ||
if (!files.length) cb(new Error('No file found.')); | ||
else cb(null, path.join(dir, files[0])); | ||
}); | ||
}); | ||
return files[0] != null ? path.join(dir, files[0]) : null; | ||
}; | ||
// Return content of first existing file in argument list. | ||
var readFirstFileSync = function() { | ||
var files = [].slice.call(arguments); | ||
for (var i = 0, len = files.length; i < len; i++) { | ||
if (path.existsSync(files[i])) { | ||
return readFileSync(files[i]); | ||
var getFiles = function(inPath, cb) { | ||
fs.stat(inPath, function(err, stat) { | ||
if (err != null) return cb(err); | ||
if (stat.isFile()) { | ||
cb(null, [ inPath ]); | ||
} else { | ||
var finder = findit.find(inPath); | ||
var files = []; | ||
finder.on('file', function(file) { files.push(file); }); | ||
finder.on('end', function() { cb(null, files); }); | ||
} | ||
} | ||
return ''; | ||
}); | ||
}; | ||
@@ -79,8 +103,24 @@ | ||
var preprocess = function(file, pp, options, cb) { | ||
// stdin would have been nice here, but not all preprocessors (less) | ||
// accepts that, so we need to read the file both here and for the parser. | ||
if (pp != null) { | ||
exec(pp + ' ' + file, function(err, stdout, stderr) { | ||
// log('styledocco: preprocessing ' + file + ' with ' + pp); | ||
// Fail gracefully on preprocessor errors | ||
if (err != null) console.error(err.message); | ||
if (stderr.length && options.verbose) console.error(stderr); | ||
cb(null, stdout || ''); | ||
}); | ||
} else { | ||
fs.readFile(file, 'utf8', cb); | ||
} | ||
}; | ||
var cli = function(options) { | ||
// Config | ||
var defaultResourceDir = path.resolve(__dirname, 'resources'); | ||
var resourcesDir = __dirname + '/share/'; | ||
// Filetypes and matching preprocessor binaries | ||
// Filetypes and matching preprocessor binaries. | ||
var fileTypes = { | ||
@@ -97,130 +137,162 @@ '.css': null, | ||
mkdirp(options.out); | ||
// Compile custom or default template | ||
var template = jade.compile( | ||
readFirstFileSync(options.resources + '/docs.jade', | ||
defaultResourceDir + '/docs.jade') | ||
); | ||
// Get custom or default JS and CSS files | ||
var staticFiles = { | ||
'docs.js': readFirstFileSync(options.resources + '/docs.js', | ||
defaultResourceDir + '/docs.js'), | ||
'docs.css': readFirstFileSync(options.resources + '/docs.css', | ||
defaultResourceDir + '/docs.css'), | ||
'previews.js': readFirstFileSync(options.resources + '/previews.js', | ||
defaultResourceDir + '/previews.js') | ||
// Custom error also outputing StyleDocco and Node versions. | ||
var SDError = function(msg, err) { | ||
this.message = msg + '\n' + err.message + '\n' + | ||
'StyleDocco v' + version + | ||
' running on Node ' + process.version + ' ' + process.platform; | ||
if (options.verbose) { | ||
this.message += '\nOptions: ' + JSON.stringify(options); | ||
} | ||
}; | ||
util.inherits(SDError, Error); | ||
// Get optional extra CSS for previews | ||
var previewCSS = mincss(options.include | ||
.filter(function(file) { return path.extname(file) === '.css'; }) | ||
.map(readFileSync) | ||
.reduce(add, '') | ||
); | ||
mkdirp(options.out); | ||
// Get optional extra JavaScript for previews | ||
var previewJS = minjs(options.include | ||
.filter(function(file) { return path.extname(file) === '.js'; }) | ||
.map(readFileSync) | ||
.reduce(add, '') | ||
); | ||
// Render template | ||
var render = function(source, sections, css) { | ||
if (css == null) css = ''; | ||
return template({ | ||
title: baseFilename(source), | ||
sections: sections, | ||
project: { name: options.name, menu: menu }, | ||
previewCSS: mincss(css) + previewCSS, | ||
previewJS: previewJS | ||
}); | ||
}; | ||
// Find files | ||
var files = options['in'].reduce(function(files, file) { | ||
if (fs.statSync(file).isDirectory()) { | ||
files = files.concat(findit.sync(file)); | ||
} else { | ||
files.push(file); | ||
} | ||
return files; | ||
}, []) | ||
.filter(function(file) { | ||
// No hidden files | ||
if (file.match(/(\/|^)\.[^\.\/]/)) return false; | ||
// Only supported file types | ||
if (!(path.extname(file) in fileTypes)) return false; | ||
// Files only | ||
if (!fs.statSync(file).isFile()) return false; | ||
return true; | ||
}).sort(); | ||
if (!files.length) return console.error('No files found'); | ||
var preprocess = function(file, cb) { | ||
var pp = options.preprocessor || fileTypes[path.extname(file)]; | ||
if (pp != null) { | ||
exec(pp + ' ' + file, function(err, stdout, stderr) { | ||
log('styledocco: preprocessing ' + file + ' with ' + pp); | ||
// Fail gracefully on preprocessor errors | ||
if (err != null) console.error(err.message); | ||
if (stderr.length) console.error(stderr); | ||
cb(null, stdout || ''); | ||
// Fetch all static resources. | ||
async.parallel({ | ||
template: function(cb) { | ||
fs.readFile(resourcesDir + 'docs.jade', 'utf8', function(err, contents) { | ||
if (err != null) return cb(err); | ||
cb(null, jade.compile(contents)); | ||
}); | ||
} else { | ||
fs.readFile(file, 'utf8', cb); | ||
}, | ||
docs: function(cb) { | ||
async.parallel({ | ||
css: async.apply(fs.readFile, resourcesDir + 'docs.css', 'utf8'), | ||
js: function(cb) { | ||
async.parallel([ | ||
async.apply(fs.readFile, resourcesDir + 'docs.ui.js', 'utf8'), | ||
async.apply(fs.readFile, resourcesDir + 'docs.previews.js', 'utf8') | ||
], function(err, res) { | ||
if (err != null) return cb(err); | ||
cb(null, res.join('')); | ||
}); | ||
} | ||
}, cb); | ||
}, | ||
// Extra JavaScript and CSS files to include in previews. | ||
previews: function(cb) { | ||
fs.readFile(resourcesDir + 'previews.js', 'utf8', function(err, js) { | ||
if (err != null) return cb(err); | ||
var code = { js: js, css: '' }; | ||
var files = options.include.filter(function(file) { | ||
return inArray(['.css', '.js'], path.extname(file)); | ||
}); | ||
async.filter(files, path.exists, function(files) { | ||
async.reduce(files, code, function(tot, cur, cb) { | ||
fs.readFile(cur, 'utf8', function(err, contents) { | ||
if (err != null) return cb(err); | ||
tot[path.extname(cur).slice(1)] += contents; | ||
cb(null, tot); | ||
}); | ||
}, cb); | ||
}); | ||
}); | ||
}, | ||
// Find input files. | ||
files: function(cb) { | ||
async.reduce(options['in'], [], function(all, cur, cb) { | ||
getFiles(cur, function(err, files) { | ||
if (err != null) return cb(err); | ||
cb(null, all.concat(files)); | ||
}); | ||
}, function(err, files) { | ||
files = files.filter(function(file) { | ||
// No hidden files | ||
if (file.match(/(\/|^)\.[^\.\/]/)) return false; | ||
// Only supported file types | ||
if (!(path.extname(file) in fileTypes)) return false; | ||
return true; | ||
}).sort(); | ||
if (!files.length) cb(new Error('Failed to process files.')); | ||
cb(null, files); | ||
}); | ||
}, | ||
// Look for a README file. | ||
readme: function(cb) { | ||
findFile(options.basePath, /^readme\.m(ark)?d(own)?/i, function(err, file) { | ||
if (file != null && err == null) return read(file); | ||
findFile(process.cwd(), /^readme\.m(ark)?d(own)?/i, function(err, file) { | ||
if (err != null) file = resourcesDir + 'README.md'; | ||
read(file); | ||
}); | ||
}); | ||
var read = function(file) { | ||
fs.readFile(file, 'utf8', function(err, content) { | ||
if (err != null) cb(err); | ||
cb(null, content); | ||
}); | ||
}; | ||
} | ||
}; | ||
// Build menu | ||
var menu = menuLinks(files, options.basePath); | ||
// Run files through preprocessor and StyleDocco parser. | ||
async.mapSeries(files, function(file, cb) { | ||
preprocess(file, function(err, css) { | ||
cb(null, { | ||
path: file, | ||
css: css | ||
}, function(err, resources) { | ||
if (err != null) throw new SDError('Could not process files.', err); | ||
var menu = menuLinks(resources.files, options.basePath); | ||
// Run files through preprocessor and StyleDocco parser. | ||
async.map(resources.files, function(file, cb) { | ||
async.parallel({ | ||
css: async.apply(preprocess, file, | ||
options.preprocessor || fileTypes[path.extname(file)], options), | ||
docs: function(cb) { | ||
fs.readFile(file, 'utf8', function(err, code) { | ||
if (err != null) return cb(err); | ||
cb(null, styledocco(code)); | ||
}); | ||
} | ||
}, function(err, data) { | ||
if (err != null) return cb(err); | ||
data.path = file; | ||
cb(null, data); | ||
}); | ||
}, function(err, files) { | ||
if (err != null) throw err; | ||
// Get the combined CSS from all files. | ||
var previewStyles = pluck(files, 'css').join(''); | ||
previewStyles += resources.previews.css; | ||
// Build a JSON string of all files and their headings, for client side search. | ||
var searchIndex = flatten(files.map(function(file) { | ||
var arr = [ { title: baseFilename(file.path), | ||
filename: basePathname(file.path, options.basePath), | ||
url: htmlFilename(file.path, options.basePath) } ]; | ||
return arr.concat(file.docs.map(function(section) { | ||
return { title: section.title, | ||
filename: basePathname(file.path, options.basePath), | ||
url: htmlFilename(file.path, options.basePath) + '#' + section.slug }; | ||
})); | ||
})); | ||
searchIndex = 'var searchIndex=' + JSON.stringify(searchIndex) + ';'; | ||
var docsScript = '(function(){' + searchIndex + resources.docs.js + '})();'; | ||
// Render files | ||
var htmlFiles = files.map(function(file) { | ||
return { | ||
path: file.path, | ||
html: resources.template({ | ||
title: baseFilename(file.path), | ||
sections: file.docs, | ||
project: { name: options.name, menu: menu }, | ||
resources: { | ||
docs: { js: minjs(docsScript), css: mincss(resources.docs.css) }, | ||
previews: { js: minjs(resources.previews.js), css: mincss(previewStyles) } | ||
} | ||
}) | ||
}; | ||
}); | ||
// Add readme with "fake" index path. | ||
htmlFiles.push({ | ||
path: path.join(options.basePath, 'index'), | ||
html: resources.template({ | ||
title: '', | ||
sections: styledocco.makeSections([{ docs: resources.readme, code: '' }]), | ||
project: { name: options.name, menu: menu }, | ||
resources: { | ||
docs: { js: minjs(docsScript), css: mincss(resources.docs.css) } | ||
} | ||
}) | ||
}); | ||
// Write files to the output dir. | ||
htmlFiles.forEach(function(file) { | ||
var dest = path.join(options.out, htmlFilename(file.path, options.basePath)); | ||
log('styledocco: writing ' + file.path + ' -> ' + dest); | ||
fs.writeFileSync(dest, file.html); | ||
}); | ||
}); | ||
}, function(err, htmlFiles) { | ||
var css = htmlFiles.reduce(function(css, file) { | ||
return css + file.css; | ||
}, ''); | ||
htmlFiles = htmlFiles.map(function(file) { | ||
return { | ||
path: file.path, | ||
html: render(file.path, styledocco(readFileSync(file.path)), css) | ||
}; | ||
}); | ||
// Look for a README file. | ||
var readmeFile = findFile(options.basePath, /^readme/i) || | ||
findFile(process.cwd(), /^readme/i) || | ||
findFile(options.resources, /^readme/i) || | ||
defaultResourceDir + '/README.md'; | ||
// Add readme with "fake" index path | ||
htmlFiles.push({ | ||
path: path.join(options.basePath, 'index'), | ||
html: render('', styledocco.makeSections([ { docs: readFileSync(readmeFile), code: '' } ]), css) | ||
}); | ||
// Write files to the output dir. | ||
htmlFiles.forEach(function(file) { | ||
var dest = path.join(options.out, htmlFilename(file.path, options.basePath)); | ||
log('styledocco: writing ' + file.path + ' -> ' + dest); | ||
fs.writeFileSync(dest, file.html); | ||
}); | ||
// Write static resources to the output dir | ||
Object.keys(staticFiles).forEach(function(file) { | ||
var dest = path.join(options.out, file); | ||
log('styledocco: writing ' + file + ' -> ' + dest); | ||
fs.writeFileSync(dest, staticFiles[file]); | ||
}); | ||
}); | ||
@@ -227,0 +299,0 @@ }; |
{ | ||
"name": "styledocco", | ||
"description": "Generate style guides and documentation from your stylesheets.", | ||
"keywords": [ "styleguide", "css", "documentation" ], | ||
"description": "Generate documentation and style guides with design patterns from stylesheets.", | ||
"keywords": [ "styleguide", "css", "documentation", "design", "patterns" ], | ||
"author": "Jacob Rask <jacob@jacobrask.net>", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"homepage": "http://jacobrask.github.com/styledocco/", | ||
"licenses": [ { "type": "MIT", "url": "http://github.com/jacobrask/styledocco/raw/master/LICENSE" } ], | ||
"contributors": [ "Jacob Rask <jacob@jacobrask.net>" ], | ||
"bugs": { "url": "https://github.com/jacobrask/styledocco/issues" }, | ||
"repository": { "type": "git", "url": "git://github.com/jacobrask/styledocco.git" }, | ||
"engines": { "node": ">=0.4.0" }, | ||
"preferGlobal": true, | ||
"dependencies": { | ||
"async": "0.1.x", | ||
"clean-css": "0.4.x", | ||
"findit": "0.x.x", | ||
@@ -23,3 +24,2 @@ "jade": "0.23.x", | ||
"browserify": "1.13.x", | ||
"jquery-browserify": "1.7.x", | ||
"jshint": "0.7.x", | ||
@@ -31,5 +31,4 @@ "nodeunit": "0.7.x" | ||
"scripts": { | ||
"test": "nodeunit test", | ||
"prepublish": "make" | ||
"test": "nodeunit test" | ||
} | ||
} |
@@ -6,7 +6,7 @@ StyleDocco | ||
Stylesheet comments will be parsed through [Markdown](http://en.wikipedia.org/wiki/Markdown) and displayed in a generated HTML document. You can write HTML code prefixed with 4 spaces or between [code fences](http://github.github.com/github-flavored-markdown/) (<code>```</code>) in your comments, and StyleDocco renders a preview with the styles applied, and shows the example HTML code. | ||
Stylesheet comments will be parsed through [Markdown](http://en.wikipedia.org/wiki/Markdown) and displayed in a generated HTML document. You can write HTML code prefixed with 4 spaces or between [code fences](http://github.github.com/github-flavored-markdown/) (<code>```</code>) in your comments, and StyleDocco show a preview with the styles applied, and displays the example HTML code. | ||
An important philosophy of StyleDocco is to introduce as little custom syntax as possible, maintaining the stylesheet comments readable and useful even without StyleDocco. | ||
The previews are rendered in a resizable iframes to make it easy to demonstrate responsive designs at different viewport sizes. | ||
Suggestions, feature requests and bug reports are very welcome, either at [GitHub](https://github.com/jacobrask/styledocco/issues) or on Twitter ([@jacobrask](https://twitter.com/jacobrask)). | ||
Suggestions, feature requests and bug reports are welcome either at [GitHub](https://github.com/jacobrask/styledocco/issues) or on Twitter ([@jacobrask](https://twitter.com/jacobrask)). | ||
@@ -17,5 +17,5 @@ | ||
StyleDocco requires [Node.js](http://nodejs.org). After installing Node.js, run `npm install -g styledocco` or clone this repository. | ||
StyleDocco requires [Node.js](http://nodejs.org). After installing Node.js, run `npm install -fg styledocco` or clone this repository and run `./bin/styledocco`. | ||
StyleDocco is free software, released under the [MIT license](https://raw.github.com/jacobrask/styledocco/master/LICENSE). | ||
StyleDocco is free and open source software, released under the [MIT license](https://raw.github.com/jacobrask/styledocco/master/LICENSE). | ||
@@ -26,18 +26,13 @@ | ||
`styledocco [options] [INPUT]` | ||
`styledocco [options] [STYLESHEET(S)]` | ||
StyleDocco will automatically compile any SASS, SCSS, Less or Stylus files before they are applied to the page. You can also enter a custom preprocessor command if you want to pass custom parameters to the preprocessor. | ||
If your project includes a `README` file, it will be used as the base for an `index.html`. StyleDocco will also add some default styles to your documentation, but they are easy to modify to make it fit with your project. | ||
Options | ||
------- | ||
* `--name`, `-n` Name of the project *(required)* | ||
* `--name`, `-n` Name of the project | ||
* `--out`, `-o` Output directory *(default: "docs")* | ||
* `--resources`, `-s` Directory with files to customize the documentation output. StyleDocco defaults will be used for any required file not found in this directory. *(optional)* | ||
* `--preprocessor` Custom preprocessor command. *(optional)* (ex: `--preprocessor "scss --load-path=deps/"`) | ||
* `--preprocessor` Custom preprocessor command. *(optional)* (ex: `--preprocessor "~/bin/lessc"`) | ||
* `--include` Include specified CSS and/or JavaScript files in the previews. *(optional)* (ex: `--include mysite.css --include app.js`) | ||
* `--verbose` Show log messages when generating the documentation. *(default: false)* | ||
* Directory containing the stylesheets to document. | ||
* Stylesheet (or directory of stylesheets) to process. | ||
@@ -51,5 +46,5 @@ Usage examples | ||
Generate documentation for *My Project* in the `mydocs` folder, from source files in the `styles` folder. Use the Less binary in `~/bin/lessc`. | ||
Generate documentation for *My Project* in the `mydocs` folder, from source files in the `styles` folder. Use the `--compass` option for SASS to make Compass imports available. | ||
`styledocco -n "My Project" -o mydocs -s mydocs --preprocessor "~/bin/lessc" styles` | ||
`styledocco -n "My Project" -o mydocs -s mydocs --preprocessor "scss --compass" styles` | ||
@@ -77,2 +72,5 @@ | ||
* StyleDocco will automatically compile any SASS, SCSS, Less or Stylus files before they are applied to the page. You can also enter a custom preprocessor command if you want to pass custom parameters to the preprocessor. | ||
* If your project includes a `README.md` file, it will be used as the base for an `index.html`. | ||
* If you don't specify a custom name, StyleDocco will use the name from a `package.json` file if it finds one. | ||
* Put some whitespace before a comment block to exclude it from the documentation. | ||
@@ -79,0 +77,0 @@ * Level 1 headings will automatically create a new section in the documentation. |
@@ -14,2 +14,11 @@ 'use strict'; | ||
// Make an URL slug from `str`. | ||
var slugify = function(str) { | ||
return encodeURIComponent( | ||
str.trim().toLowerCase() | ||
.replace(/[^\w ]+/g,'') | ||
.replace(/ +/g,'-') | ||
); | ||
}; | ||
// Check if a string is code or a comment (and which type of comment). | ||
@@ -46,3 +55,3 @@ var checkType = function(str) { | ||
// Trim newlines from beginning and end of multi line string. | ||
// Trim newlines from beginning and end of a multi line string. | ||
var trimNewLines = function(str) { | ||
@@ -78,13 +87,16 @@ return str.replace(/^\n*/, '').replace(/\n*$/, ''); | ||
var htmlEntities = function(str) { | ||
return str.replace(/</g, '<'); | ||
}; | ||
var makeSections = exports.makeSections = function(blocks) { | ||
return blocks | ||
.map(function(block) { | ||
// Run comments through marked.lexer to get Markdown tokens | ||
return { | ||
docs: marked.lexer(block.docs), | ||
code: block.code | ||
}; | ||
// Run comments through marked.lexer to get Markdown tokens. | ||
block.docs = marked.lexer(block.docs); | ||
return block; | ||
}) | ||
.map(function(block) { | ||
// If we encounter code blocks in documentation, add preview HTML | ||
// If we encounter code blocks in documentation, add preview HTML. | ||
var newBlock = { | ||
@@ -94,7 +106,15 @@ code: block.code, | ||
if (token.type === 'code' && (token.lang == null || token.lang === 'html')) { | ||
tokens.push({ | ||
type: 'html', | ||
pre: true, | ||
text: '<div class="preview">' + token.text + '</div>' | ||
}); | ||
token.type = 'html'; | ||
token.pre = true; | ||
token.text = '<textarea class="preview-code" spellcheck="false">' + htmlEntities(token.text) + '</textarea>'; | ||
// Add permalink `id`s and some custom properties to headings. | ||
} else if (token.type === 'heading') { | ||
var slug = slugify(token.text); | ||
token.type = 'html'; | ||
token._slug = slug; | ||
token._origText = token.text; | ||
// This token should start a new doc section | ||
if (token.depth === 1) token._split = true; | ||
token.text = '<h' + token.depth + ' id="' + slug + '">' + | ||
token.text + '</h' + token.depth + '>\n'; | ||
} | ||
@@ -113,15 +133,8 @@ tokens.push(token); | ||
while (docs.length) { | ||
if (docs[0].type === 'heading' && docs[0].depth === 1) { | ||
// New section, add title property and strip heading. | ||
var title = docs[0].text; | ||
docs.shift(); | ||
if (docs.length === 0) { | ||
// Nothing more after the heading in the doc block, start new section. | ||
sections.push({ docs: [], code: '', title: title }); | ||
} else { | ||
sections.push({ docs: [ docs.shift() ], code: '', title: title }); | ||
} | ||
// First section | ||
} else if (sections.length === 0) { | ||
sections.push({ docs: [ docs.shift() ], code: '', title: null }); | ||
// New or first section, add title/slug properties. | ||
if (docs[0]._split || sections.length === 0) { | ||
var title = docs[0]._origText; | ||
var slug = docs[0]._slug; | ||
sections.push({ docs: [ docs.shift() ], code: '', | ||
title: title, slug: slug }); | ||
} else { | ||
@@ -147,2 +160,3 @@ // Add the documentation to the last section. | ||
title: section.title ? section.title.trim() : '', | ||
slug: section.slug || '', | ||
docs: trimNewLines(marked.parser(section.docs)), | ||
@@ -157,3 +171,4 @@ code: trimNewLines(section.code) | ||
}; | ||
module.exports.makeSections = makeSections; | ||
module.exports.separate = separate; |
Sorry, the diff of this file is not supported yet
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
3
23
1341
55575
8
80
2
+ Addedclean-css@0.4.x
+ Addedclean-css@0.4.2(transitive)
+ Addedoptimist@0.3.7(transitive)