grunt-literate
Advanced tools
Comparing version 0.1.5 to 0.2.0
@@ -5,2 +5,24 @@ ## beautiful-docs | ||
Check [`Gruntfile.js`](https://github.com/phadej/grunt-literate/blob/master/Gruntfile.js) in the repository for an example. | ||
It's easy to start, you only need to configure `literate` and `bfdocs` tasks: | ||
```js | ||
grunt.initConfig({ | ||
literate: { | ||
"README.md": ["lib/*.js"] | ||
}, | ||
bfdocs: { | ||
docs: { | ||
options: { | ||
title: "My fabulous documentation", | ||
manifest: { | ||
files: [ "README.md" ], | ||
}, | ||
dest: "doc/", | ||
theme: "default", | ||
} | ||
} | ||
}, | ||
}); | ||
``` | ||
or check [`Gruntfile.js`](https://github.com/phadej/grunt-literate/blob/master/Gruntfile.js) in the repository for the real example. |
## Release History | ||
- 0.2.0 Split out | ||
- Library is in [ljs](https://github.com/phadej/ljs) package now | ||
- 0.1.5 Maintenance release | ||
@@ -4,0 +6,0 @@ - Updated dependencies |
@@ -18,4 +18,2 @@ /* | ||
"Gruntfile.js", | ||
"lib/*.js", | ||
"bin/*.js", | ||
"tasks/*.js", | ||
@@ -44,3 +42,5 @@ ], | ||
title: "Grunt literate", | ||
manifest: "bfdocs-manifest.json", | ||
manifest: { | ||
files: [ "README.md" ], | ||
}, | ||
dest: "documentation/", | ||
@@ -64,2 +64,5 @@ theme: "default", | ||
// Docs task | ||
grunt.registerTask("docs", ["literate", "bfdocs"]); | ||
// By default, lint and run all tests. | ||
@@ -66,0 +69,0 @@ grunt.registerTask("default", ["jshint"]); |
{ | ||
"name": "grunt-literate", | ||
"description": "Generate docs from your source", | ||
"version": "0.1.5", | ||
"version": "0.2.0", | ||
"homepage": "https://github.com/phadej/grunt-literate", | ||
@@ -24,6 +24,2 @@ "author": { | ||
], | ||
"main": "lib/literate.js", | ||
"bin": { | ||
"ljs": "./bin/ljs.js" | ||
}, | ||
"engines": { | ||
@@ -55,6 +51,4 @@ "node": ">= 0.8.0" | ||
"dependencies": { | ||
"esprima": "~1.0.4", | ||
"optimist": "~0.6.0", | ||
"glob": "~3.2.6" | ||
"ljs": "~0.2.0" | ||
} | ||
} |
@@ -42,3 +42,3 @@ # grunt-literate | ||
The source will be parsed as JavaScript, and `/** ... ` comments extracted to the destionation file. | ||
The source will be parsed as JavaScript, and `/** ... ` comments extracted to the destination file. | ||
This example uses markdown, but you are free to use any format, or even just plain text. | ||
@@ -58,31 +58,31 @@ | ||
### Lex.js | ||
This is for demo of `/// include` directive. | ||
## beautiful-docs | ||
### Library | ||
This package plays well with [beautiful-docs](http://beautifuldocs.com/) and [grunt-beautiful-docs](https://www.npmjs.org/package/grunt-beautiful-docs) especially. | ||
You can also use *grunt-literate* as a normal library: | ||
It's easy to start, you only need to configure `literate` and `bfdocs` tasks: | ||
```js | ||
grunt.initConfig({ | ||
literate: { | ||
"README.md": ["lib/*.js"] | ||
}, | ||
bfdocs: { | ||
docs: { | ||
options: { | ||
title: "My fabulous documentation", | ||
manifest: { | ||
files: [ "README.md" ], | ||
}, | ||
dest: "doc/", | ||
theme: "default", | ||
} | ||
} | ||
}, | ||
}); | ||
``` | ||
var documentation = require("grunt-literate")("hello.js", { code: true }); | ||
``` | ||
### ljs | ||
or check [`Gruntfile.js`](https://github.com/phadej/grunt-literate/blob/master/Gruntfile.js) in the repository for the real example. | ||
If `grunt-literate` is installed globally, | ||
you can use `ljs` command line tool to process your literate javascript files | ||
```sh | ||
$ ljs -c -o foo.md foo.js | ||
$ ljs --help | ||
``` | ||
## beautiful-docs | ||
This package plays well with [beautiful-docs](http://beautifuldocs.com/) and [grunt-beautiful-docs](https://www.npmjs.org/package/grunt-beautiful-docs) especially. | ||
Check [`Gruntfile.js`](https://github.com/phadej/grunt-literate/blob/master/Gruntfile.js) in the repository for an example. | ||
## Contributing | ||
@@ -97,2 +97,4 @@ | ||
- 0.2.0 Split out | ||
- Library is in [ljs](https://github.com/phadej/ljs) package now | ||
- 0.1.5 Maintenance release | ||
@@ -112,10 +114,2 @@ - Updated dependencies | ||
## Related work | ||
This task could be abused to do literate programming. | ||
[Docco](http://jashkenas.github.io/docco/) is similar tool, | ||
however *literate* is markup-language-agnostic. | ||
## LICENSE | ||
Copyright Oleg Grenrus 2013 | ||
@@ -122,0 +116,0 @@ |
@@ -54,3 +54,3 @@ | ||
The source will be parsed as JavaScript, and `/** ... ` comments extracted to the destionation file. | ||
The source will be parsed as JavaScript, and `/** ... ` comments extracted to the destination file. | ||
This example uses markdown, but you are free to use any format, or even just plain text. | ||
@@ -70,354 +70,31 @@ | ||
### Lex.js | ||
This is for demo of `/// include` directive. | ||
## beautiful-docs | ||
This package plays well with [beautiful-docs](http://beautifuldocs.com/) and [grunt-beautiful-docs](https://www.npmjs.org/package/grunt-beautiful-docs) especially. | ||
```js | ||
"use strict"; | ||
It's easy to start, you only need to configure `literate` and `bfdocs` tasks: | ||
var esprima = require("esprima"); | ||
function lex(contents) { | ||
var syntax = esprima.parse(contents, { | ||
tokens: true, | ||
loc: true, | ||
range: true, | ||
comment: true | ||
}); | ||
var tokens = []; | ||
var currRange = 0; | ||
function addWhitespace(from, to) { | ||
var ws; | ||
var comments = syntax.comments.filter(function (comment) { | ||
return comment.range[0] >= from && comment.range[1] <= to; | ||
}); | ||
comments.forEach(function (comment) { | ||
if (comment.range[0] !== from) { | ||
ws = contents.substr(from, comment.range[0] - from); | ||
tokens.push({ | ||
type: "Whitespace", | ||
value: ws, | ||
range: [ | ||
from, | ||
comment.range[0] | ||
] | ||
}); | ||
} | ||
tokens.push({ | ||
type: "Comment", | ||
value: comment, | ||
range: comment.range, | ||
}); | ||
from = comment.range[1]; | ||
}); | ||
if (from !== to) { | ||
ws = contents.substr(from, to - from); | ||
tokens.push({ | ||
type: "Whitespace", | ||
value: ws, | ||
range: [ | ||
from, | ||
to | ||
] | ||
}); | ||
} | ||
} | ||
// Go thru all tokens esprima returns | ||
syntax.tokens.forEach(function (token) { | ||
// Some comments and whitespace skipped | ||
if (token.range[0] !== currRange) { | ||
addWhitespace(currRange, token.range[0]); | ||
} | ||
tokens.push(token); | ||
currRange = token.range[1]; | ||
}); | ||
// trailing whitespace | ||
if (contents.length !== currRange) { | ||
addWhitespace(currRange, contents.length); | ||
} | ||
return tokens; | ||
} | ||
module.exports = lex; | ||
"use strict"; | ||
``` | ||
### Library | ||
You can also use *grunt-literate* as a normal library: | ||
``` | ||
var documentation = require("grunt-literate")("hello.js", { code: true }); | ||
``` | ||
```js | ||
var lex = require("./lex.js"); | ||
var fs = require("fs"); | ||
var path = require("path"); | ||
var assert = require("assert"); | ||
var glob = require("glob"); | ||
var whitespaceEndRe = /^\s*$/; | ||
var whitespaceRe = /^(\s*)/; | ||
function isWhitespace(str) { | ||
return whitespaceEndRe.test(str); | ||
} | ||
function find(array, predicate) { | ||
for (var i = 0; i < array.length; i++) { | ||
if (predicate(array[i])) { | ||
return array[i]; | ||
} | ||
} | ||
} | ||
function stripShebang(contents) { | ||
var m = contents.match(/^#!\/[^\n]*\n/); | ||
return m ? contents.substr(m[0].length) : contents; | ||
} | ||
function fileDirective(filename, value, regexp, callback) { | ||
var m = value.match(regexp); | ||
if (m) { | ||
var directivePattern = m[1]; | ||
var globPattern = path.join(path.dirname(filename), directivePattern); | ||
var files = glob.sync(globPattern); | ||
if (files.length === 0) { | ||
throw new Error(directivePattern + " doesn't match any files"); | ||
} | ||
files.forEach(callback); | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
function getTokens(filename) { | ||
var contents = fs.readFileSync(filename).toString(); | ||
contents = stripShebang(contents); | ||
var tokens = lex(contents); | ||
var resTokens = []; | ||
tokens.forEach(function (token) { | ||
var r; | ||
if (token.type === "Comment" && token.value.type === "Line" && token.value.value[0] === "/") { | ||
var value = token.value.value.substr(1); | ||
r = fileDirective(filename, value, /^\s*plain\s+(.*?)\s*$/, function (includename) { | ||
resTokens.push({ | ||
type: "Plain", | ||
value: fs.readFileSync(includename).toString(), | ||
}); | ||
}); | ||
if (r) { return; } | ||
r = fileDirective(filename, value, /^\s*include\s+(.*?)\s*$/, function (includename) { | ||
resTokens = resTokens.concat(getTokens(includename)); | ||
}); | ||
if (r) { return; } | ||
assert(false, "unknown directive: " + value); | ||
} else { | ||
token.raw = contents.substr(token.range[0], token.range[1] - token.range[0]); | ||
resTokens.push(token); | ||
} | ||
}); | ||
return resTokens; | ||
} | ||
function literate(filename, opts) { | ||
opts = opts || {}; | ||
var code = opts.code || false; | ||
var codeOpen = opts.codeOpen || "\n```js\n"; | ||
var codeClose = opts.codeClose || "\n```\n\n"; | ||
var tokens = getTokens(filename); | ||
var state = "code"; | ||
var content = ""; | ||
var tmp = ""; // buffer for code output | ||
function appendCode() { | ||
if (state === "code") { | ||
state = "text"; | ||
if (!isWhitespace(tmp)) { | ||
content += codeOpen + tmp.replace(/^[\s\n]*/, "").replace(/[\s\n]*$/, "") + codeClose; | ||
grunt.initConfig({ | ||
literate: { | ||
"README.md": ["lib/*.js"] | ||
}, | ||
bfdocs: { | ||
docs: { | ||
options: { | ||
title: "My fabulous documentation", | ||
manifest: { | ||
files: [ "README.md" ], | ||
}, | ||
dest: "doc/", | ||
theme: "default", | ||
} | ||
tmp = ""; | ||
} | ||
} | ||
tokens.forEach(function (token) { | ||
if (token.type === "Plain") { | ||
appendCode(); | ||
content += "\n" + token.value; | ||
} else if (token.type === "Comment" && token.value.type === "Block" && token.value.value[0] === "*") { | ||
appendCode(); | ||
// literate comment | ||
var comment = token.value; | ||
// block comment starting with /** | ||
var value = comment.value.slice(1); | ||
var lines = value.split(/\n/); | ||
var first = find(lines, function (line) { return !isWhitespace(line); } ); | ||
var indent = first ? whitespaceRe.exec(first)[1] : ""; | ||
// Drop empty lines at the beginning of the literate comment | ||
while (true) { | ||
if (lines[0] !== undefined && isWhitespace(lines[0])) { | ||
lines.shift(); | ||
} else { | ||
break; | ||
} | ||
} | ||
// unindent lines | ||
lines = lines.map(function (line) { | ||
if (line.indexOf(indent) === 0) { | ||
return line.replace(indent, ""); | ||
} else if (isWhitespace(line)) { | ||
return ""; | ||
} else { | ||
return line; | ||
} | ||
}); | ||
// Each line should have newline char after, also the last | ||
content += lines.join("\n") + "\n"; | ||
} else if (code) { | ||
// Code | ||
if (state !== "code") { | ||
state = "code"; | ||
tmp = ""; | ||
} | ||
tmp += token.raw; | ||
} | ||
}); | ||
// Append code at end of the file | ||
appendCode(); | ||
// Just one newline at eof | ||
content = content.replace(/\n+$/, "\n"); | ||
return content; | ||
} | ||
module.exports = literate; | ||
``` | ||
### ljs | ||
If `grunt-literate` is installed globally, | ||
you can use `ljs` command line tool to process your literate javascript files | ||
```sh | ||
$ ljs -c -o foo.md foo.js | ||
$ ljs --help | ||
``` | ||
```js | ||
"use strict"; | ||
var optimist = require("optimist"); | ||
var fs = require("fs"); | ||
var literate = require("../lib/literate.js"); | ||
optimist.usage("ljs [options] file.js"); | ||
optimist.boolean("h").options("h", { | ||
alias: "help", | ||
describe: "Show brief help information", | ||
}, | ||
}); | ||
optimist.boolean("v").options("v", { | ||
alias: "version", | ||
describe: "Display version information and exit.", | ||
}); | ||
optimist.options("o", { | ||
alias: "output", | ||
describe: "Output file.", | ||
}); | ||
optimist.boolean("c").options("c", { | ||
alias: "code", | ||
describe: "Include code in output file.", | ||
default: true, | ||
}); | ||
function cli(argv) { | ||
var options = optimist.parse(argv); | ||
if (options.help) { | ||
console.log(optimist.help()); | ||
return 0; | ||
} | ||
if (options.version) { | ||
var pkg = JSON.parse(fs.readFileSync(__dirname + "/../package.json")); | ||
console.log("jsgrep, part of jsstana version " + pkg.version); | ||
return 0; | ||
} | ||
if (options._.length !== 1) { | ||
console.error("Error: input file is required"); | ||
console.log(optimist.help()); | ||
return 0; | ||
} | ||
// Literate | ||
var filename = options._[0]; | ||
var litContents; | ||
try { | ||
litContents = literate(filename, { code: options.code }); | ||
} catch (e) { | ||
console.error("Error: while literating -- " + e.message); | ||
return 1; | ||
} | ||
// Output | ||
if (options.o) { | ||
fs.writeFileSync(options.o, litContents); | ||
} else { | ||
console.log(litContents); | ||
} | ||
} | ||
var ret = cli(process.argv.slice(2)); | ||
process.exit(ret); | ||
``` | ||
or check [`Gruntfile.js`](https://github.com/phadej/grunt-literate/blob/master/Gruntfile.js) in the repository for the real example. | ||
## beautiful-docs | ||
This package plays well with [beautiful-docs](http://beautifuldocs.com/) and [grunt-beautiful-docs](https://www.npmjs.org/package/grunt-beautiful-docs) especially. | ||
Check [`Gruntfile.js`](https://github.com/phadej/grunt-literate/blob/master/Gruntfile.js) in the repository for an example. | ||
## Contributing | ||
@@ -432,2 +109,4 @@ | ||
- 0.2.0 Split out | ||
- Library is in [ljs](https://github.com/phadej/ljs) package now | ||
- 0.1.5 Maintenance release | ||
@@ -447,10 +126,2 @@ - Updated dependencies | ||
## Related work | ||
This task could be abused to do literate programming. | ||
[Docco](http://jashkenas.github.io/docco/) is similar tool, | ||
however *literate* is markup-language-agnostic. | ||
## LICENSE | ||
Copyright Oleg Grenrus 2013 | ||
@@ -490,3 +161,3 @@ | ||
var literate = require("../lib/literate.js"); | ||
var literate = require("ljs"); | ||
var assert = require("assert"); | ||
@@ -493,0 +164,0 @@ |
@@ -53,3 +53,3 @@ // vim: set sts=2 sw=2 ts=2 et: | ||
The source will be parsed as JavaScript, and `/** ... ` comments extracted to the destionation file. | ||
The source will be parsed as JavaScript, and `/** ... ` comments extracted to the destination file. | ||
This example uses markdown, but you are free to use any format, or even just plain text. | ||
@@ -69,8 +69,5 @@ | ||
*/ | ||
/// include ../lib/* | ||
/// include ../bin/ljs.js | ||
/// plain ../beautiful-docs.md | ||
/// plain ../CONTRIBUTING.md | ||
/// plain ../CHANGELOG.md | ||
/// plain ../footer.md | ||
/// plain ../LICENSE | ||
@@ -80,3 +77,3 @@ | ||
var literate = require("../lib/literate.js"); | ||
var literate = require("ljs"); | ||
var assert = require("assert"); | ||
@@ -83,0 +80,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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
2
0
19366
12
130
141
1
+ Addedljs@~0.2.0
+ Addedcommander@2.3.0(transitive)
+ Addedesprima@1.2.5(transitive)
+ Addedglob@4.0.6(transitive)
+ Addedgraceful-fs@3.0.12(transitive)
+ Addedljs@0.2.5(transitive)
+ Addedminimatch@1.0.0(transitive)
+ Addednatives@1.1.6(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedwrappy@1.0.2(transitive)
- Removedesprima@~1.0.4
- Removedglob@~3.2.6
- Removedoptimist@~0.6.0
- Removedminimist@0.0.10(transitive)
- Removedoptimist@0.6.1(transitive)
- Removedwordwrap@0.0.3(transitive)