grunt-literate
Advanced tools
Comparing version 0.1.2 to 0.1.3
"use strict"; | ||
/** | ||
#### lib/literate.js | ||
This is the heart of this task. Check the file, if you're interested | ||
*NOTE* this is demo of `include` directive | ||
*/ | ||
var lex = require("./lex.js"); | ||
var fs = require("fs"); | ||
var path = require("path"); | ||
var assert = require("assert"); | ||
@@ -20,3 +31,39 @@ var whitespaceEndRe = /^\s*$/; | ||
function literate(contents, opts) { | ||
function getTokens(filename) { | ||
var contents = fs.readFileSync(filename).toString(); | ||
var tokens = lex(contents); | ||
var m, value, includename; | ||
var resTokens = []; | ||
tokens.forEach(function (token) { | ||
if (token.type === "Comment" && token.value.type === "Line" && token.value.value[0] === "/") { | ||
value = token.value.value.substr(1); | ||
m = value.match(/^\s*plain\s+(.*?)\s*$/); | ||
if (m) { | ||
includename = path.join(path.dirname(filename), m[1]); | ||
resTokens.push({ | ||
type: "Plain", | ||
value: fs.readFileSync(includename).toString(), | ||
}); | ||
return; | ||
} | ||
m = value.match(/^\s*include\s+(.*?)\s*$/); | ||
if (m) { | ||
includename = path.join(path.dirname(filename), m[1]); | ||
resTokens = resTokens.concat(getTokens(includename)); | ||
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 || {}; | ||
@@ -27,3 +74,4 @@ var code = opts.code || false; | ||
var tokens = lex(contents); | ||
var tokens = getTokens(filename); | ||
var state = "code"; | ||
@@ -45,5 +93,9 @@ var content = ""; | ||
tokens.forEach(function (token) { | ||
if (token.type === "Comment" && token.value.type === "Block" && token.value.value[0] === "*") { | ||
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 | ||
@@ -79,3 +131,3 @@ var comment = token.value; | ||
// Each line should have newline char after, also the last | ||
// Each line should have newline char after, also the last | ||
content += lines.join("\n") + "\n"; | ||
@@ -89,3 +141,3 @@ } else if (code) { | ||
tmp += contents.substr(token.range[0], token.range[1] - token.range[0]); | ||
tmp += token.raw; | ||
} | ||
@@ -92,0 +144,0 @@ }); |
{ | ||
"name": "grunt-literate", | ||
"description": "Generate docs from your source", | ||
"version": "0.1.2", | ||
"version": "0.1.3", | ||
"homepage": "https://github.com/phadej/grunt-literate", | ||
@@ -6,0 +6,0 @@ "author": { |
@@ -5,2 +5,4 @@ # grunt-literate | ||
[![Code Climate](https://codeclimate.com/github/phadej/grunt-literate.png)](https://codeclimate.com/github/phadej/grunt-literate) | ||
## Getting Started | ||
@@ -43,4 +45,19 @@ | ||
There are no options yet. | ||
- `boolean code = false`, whether to include code parts or not | ||
### Directives | ||
Comments starting with triple slash `///` are directive comments. Currently supported directives are: | ||
- `include` _filename_: include process _filename_ here. | ||
- `plain` _filename_: include _filename_ here, without any processing, as is. | ||
#### lib/literate.js | ||
This is the heart of this task. Check the file, if you're interested | ||
*NOTE* this is demo of `include` directive | ||
## Contributing | ||
@@ -55,2 +72,3 @@ | ||
- 0.1.3 Directives | ||
- 0.1.2 Newline improvements | ||
@@ -57,0 +75,0 @@ - Newline at the end of comment |
@@ -17,2 +17,4 @@ | ||
[![Code Climate](https://codeclimate.com/github/phadej/grunt-literate.png)](https://codeclimate.com/github/phadej/grunt-literate) | ||
## Getting Started | ||
@@ -55,4 +57,168 @@ | ||
There are no options yet. | ||
- `boolean code = false`, whether to include code parts or not | ||
### Directives | ||
Comments starting with triple slash `///` are directive comments. Currently supported directives are: | ||
- `include` _filename_: include process _filename_ here. | ||
- `plain` _filename_: include _filename_ here, without any processing, as is. | ||
```js | ||
"use strict"; | ||
``` | ||
#### lib/literate.js | ||
This is the heart of this task. Check the file, if you're interested | ||
*NOTE* this is demo of `include` directive | ||
```js | ||
var lex = require("./lex.js"); | ||
var fs = require("fs"); | ||
var path = require("path"); | ||
var assert = require("assert"); | ||
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 getTokens(filename) { | ||
var contents = fs.readFileSync(filename).toString(); | ||
var tokens = lex(contents); | ||
var m, value, includename; | ||
var resTokens = []; | ||
tokens.forEach(function (token) { | ||
if (token.type === "Comment" && token.value.type === "Line" && token.value.value[0] === "/") { | ||
value = token.value.value.substr(1); | ||
m = value.match(/^\s*plain\s+(.*?)\s*$/); | ||
if (m) { | ||
includename = path.join(path.dirname(filename), m[1]); | ||
resTokens.push({ | ||
type: "Plain", | ||
value: fs.readFileSync(includename).toString(), | ||
}); | ||
return; | ||
} | ||
m = value.match(/^\s*include\s+(.*?)\s*$/); | ||
if (m) { | ||
includename = path.join(path.dirname(filename), m[1]); | ||
resTokens = resTokens.concat(getTokens(includename)); | ||
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; | ||
} | ||
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; | ||
``` | ||
## Contributing | ||
@@ -67,2 +233,3 @@ | ||
- 0.1.3 Directives | ||
- 0.1.2 Newline improvements | ||
@@ -80,3 +247,2 @@ - Newline at the end of comment | ||
```js | ||
@@ -98,5 +264,9 @@ "use strict"; | ||
try { | ||
f.src.forEach(function (filename) { | ||
content += literate(grunt.file.read(filename), options); | ||
content += literate(filename, options); | ||
}); | ||
} catch (e) { | ||
console.log(e.stack); | ||
} | ||
@@ -103,0 +273,0 @@ // Write file |
@@ -16,2 +16,4 @@ // vim: set sts=2 sw=2 ts=2 et: | ||
[![Code Climate](https://codeclimate.com/github/phadej/grunt-literate.png)](https://codeclimate.com/github/phadej/grunt-literate) | ||
## Getting Started | ||
@@ -54,25 +56,14 @@ | ||
There are no options yet. | ||
- `boolean code = false`, whether to include code parts or not | ||
## Contributing | ||
### Directives | ||
In lieu of a formal styleguide, take care to maintain the existing coding style. | ||
Add unit tests for any new or changed functionality. | ||
Lint and test your code using [Grunt](http://gruntjs.com/). | ||
Make a pull request, but don't commit `README.md`! | ||
Comments starting with triple slash `///` are directive comments. Currently supported directives are: | ||
## Release History | ||
- `include` _filename_: include process _filename_ here. | ||
- `plain` _filename_: include _filename_ here, without any processing, as is. | ||
- 0.1.2 Newline improvements | ||
- Newline at the end of comment | ||
- Only one newline at the end of generated file | ||
- 0.1.1 Fix issue with unindenting | ||
- 0.1.0 Initial release | ||
## 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. | ||
*/ | ||
/// include ../lib/literate.js | ||
/// plain ../footer.md | ||
@@ -94,5 +85,9 @@ "use strict"; | ||
try { | ||
f.src.forEach(function (filename) { | ||
content += literate(grunt.file.read(filename), options); | ||
content += literate(filename, options); | ||
}); | ||
} catch (e) { | ||
console.log(e.stack); | ||
} | ||
@@ -99,0 +94,0 @@ // Write file |
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
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
19735
11
294
82
1