support for #docplaster

This commit is contained in:
Jay Traband 2015-10-14 12:47:22 -07:00 committed by Naomi Black
parent 593938011f
commit b7216f656a
56 changed files with 383 additions and 261 deletions

View File

@ -29,8 +29,10 @@
"del": "^1.2.0",
"dgeni": "^0.4.0",
"dgeni-packages": "^0.10.0",
"diff": "^2.1.3",
"fs-extra": "^0.24.0",
"glob": "^5.0.14",
"globule": "^0.2.0",
"gulp": "^3.5.6",
"gulp-task-listing": "^1.0.1",
"gulp-util": "^3.0.6",

View File

@ -6,7 +6,8 @@ lib-cov
*.out
*.pid
*.gz
test_fragments
test_fragments/**/*.md
!**/*.*.ovr.md
pids
logs

View File

@ -0,0 +1 @@
REN *.md ????????????????????????????????????????????????????.??????????????????.ovr.md

View File

@ -0,0 +1,65 @@
var docShredder = require('../doc-shredder');
var Q = require("q");
var del = require('del')
// delPromise is a 'promise' version of del
var delPromise = Q.denodeify(del);
var globule = require('globule');
var path = require('canonical-path');
var fs = require('fs');
var JsDiff = require('diff');
describe('doc-shredder', function() {
var _shredOptions = {
examplesDir: "test_source",
fragmentsDir: "test_fragments"
};
beforeEach(function () {
});
it('should generate expected results', function (done) {
clean(_shredOptions).then(function() {
return shred(_shredOptions);
}).then(function() {
var mdOvrPath = path.join(_shredOptions.fragmentsDir, '**/*.ovr.*');
var fileNames = globule.find([mdOvrPath]);
var errs = [];
fileNames.forEach(function(fileName) {
console.log('comparing: ' + fileName);
var origFileName = fileName.replace('.ovr.', '.');
var origSource = fs.readFileSync(origFileName, 'utf8');
var expectedSource = fs.readFileSync(fileName, 'utf8');
var diffs = JsDiff.diffLines(expectedSource, origSource);
errs = [];
diffs.forEach(function(diff) {
if (diff.added) {
errs.add(' added: --->' + diff.value);
} else if (diff.removed) {
errs.add(' removed: -->' + diff.value);
}
});
if (errs.length) {
errs.unshift('File: ' + origFileName + '\n');
}
expect(errs.length).toEqual(0, '\n' + errs.join(''));
});
done();
}).catch(function(e){
expect(e).toBeNull();
})
});
function shred(shredOptions) {
return docShredder.shred(shredOptions);
}
function clean(shredOptions) {
var cleanPath = path.join(shredOptions.fragmentsDir, '**/*.*')
return delPromise([ cleanPath, '!**/*.ovr.*']);
}
});

View File

@ -7,7 +7,7 @@ var taskListing = require('gulp-task-listing');
var docShredder = require('../doc-shredder');
var shredOptions = {
examplesDir: "test_source/foo",
examplesDir: "test_source",
fragmentsDir: "test_fragments"
};

View File

@ -0,0 +1,4 @@
```
bootstrap(AppComponent);
// to be included in bootstrap...
```

View File

@ -0,0 +1,3 @@
```
import {Component, View, bootstrap} from 'angular2/angular2';
```

View File

@ -0,0 +1,9 @@
```
import {Component, View, bootstrap} from 'angular2/angular2';
/* more code here */
// indented comment
var x = 3;
// plaster should go immediately under here.
/* more code here */
bootstrap(AppComponent);
```

View File

@ -0,0 +1,4 @@
```
bootstrap(AppComponent);
// to be included in bootstrap...
```

View File

@ -0,0 +1,3 @@
```
import {Component, View, bootstrap} from 'angular2/angular2';
```

View File

@ -0,0 +1,19 @@
```
import {Component, View, bootstrap} from 'angular2/angular2';
@Component({
selector: 'my-app'
})
@View({
template: '<h1 id="output">My first Angular 2 App</h1>'
})
class AppComponent {
}
// indented comment
var x = 3;
// plaster should go immediately under here.
bootstrap(AppComponent);
// to be included in bootstrap...
```

View File

@ -0,0 +1,8 @@
```
// indented comment
var x = 3;
// plaster should go immediately under here.
bootstrap(AppComponent);
// to be included in bootstrap...
```

View File

@ -0,0 +1,9 @@
```
import {Component, View, bootstrap} from 'angular2/angular2';
/* more code here */
// indented comment
var x = 3;
// plaster should go immediately under here.
/* more code here */
bootstrap(AppComponent);
```

View File

@ -0,0 +1,3 @@
```
angular2_1.bootstrap(AppComponent);
```

View File

@ -0,0 +1,3 @@
```
bootstrap(AppComponent);
```

View File

@ -0,0 +1,3 @@
```
var angular2_1 = require('angular2/angular2');
```

View File

@ -0,0 +1,3 @@
```
import {Component, View, bootstrap} from 'angular2/angular2';
```

View File

@ -0,0 +1,19 @@
```
var angular2_1 = require('angular2/angular2');
var AppComponent = (function () {
function AppComponent() {
}
AppComponent = __decorate([
angular2_1.Component({
selector: 'my-app'
}),
angular2_1.View({
template: '<h1 id="output">My first Angular 2 App</h1>'
}),
__metadata('design:paramtypes', [])
], AppComponent);
return AppComponent;
})();
angular2_1.bootstrap(AppComponent);
//# sourceMappingURL=main.js.map
```

View File

@ -0,0 +1,14 @@
```
import {Component, View, bootstrap} from 'angular2/angular2';
@Component({
selector: 'my-app'
})
@View({
template: '<h1 id="output">My first Angular 2 App</h1>'
})
class AppComponent {
}
bootstrap(AppComponent);
```

View File

@ -0,0 +1,7 @@
```
<body>
<my-app></my-app>
</body>
```

View File

@ -0,0 +1,4 @@
```
<script src="https://code.angularjs.org/2.0.0-alpha.26/angular2.sfx.dev.js"></script>
<script src="main.js"></script>
```

View File

@ -0,0 +1,21 @@
```
/**
* @description This function logs a string.
*/
function log() {
console.log('Logging.');
}
/**
* @description My application
*/
var myApp = {
/**
* @description Display a greeting
* @param {string} name The name of the person to greet
*/
greet: function(name) {
console.log('hello ' + name);
}
};
```

View File

@ -0,0 +1,3 @@
```
bootstrap(AppComponent);
```

View File

@ -0,0 +1,11 @@
```
@Component({
selector: 'my-app'
})
@View({
template: '<h1 id="output">My First Angular 2 App</h1>'
})
class AppComponent {
}
```

View File

@ -0,0 +1,4 @@
```
class AppComponent {
}
```

View File

@ -0,0 +1,9 @@
```
/**
* @description Display a greeting
* @param {string} name The name of the person to greet
*/
greet: function(name) {
console.log('hello ' + name);
}
```

View File

@ -0,0 +1,3 @@
```
import {Component, View, bootstrap} from 'angular2/angular2';
```

View File

@ -0,0 +1,8 @@
```
/**
* @description This function logs a string.
*/
function log() {
console.log('Logging.');
}
```

View File

@ -0,0 +1,15 @@
```
import {Component, View, bootstrap} from 'angular2/angular2';
@Component({
selector: 'my-app'
})
@View({
template: '<h1 id="output">My First Angular 2 App</h1>'
})
class AppComponent {
}
bootstrap(AppComponent);
```

View File

@ -1,4 +1,4 @@
// #docregion
```
/**
* @description This function returns a string.
*
@ -8,4 +8,5 @@
function helloWorld() {
return 'Hello World';
}
}
```

View File

@ -0,0 +1,11 @@
```
name: angular2-getting-started
version: 0.0.1
dependencies:
angular2: ^2.0.0-alpha.41
browser: ^0.10.0
transformers:
- angular2:
entry_points: web/main.dart
```

View File

@ -0,0 +1,13 @@
```
<!DOCTYPE html>
<html>
<head>
<script src="https://code.angularjs.org/2.0.0-alpha.26/angular2.sfx.dev.js"></script>
<script src="main.js"></script>
</head>
<body>
<my-app></my-app>
</body>
</html>
```

View File

@ -1,22 +0,0 @@
// #docregion
// #docregion import
import {Component, View, bootstrap} from 'angular2/angular2';
// #enddocregion
//#docregion class-w-annotations
@Component({
selector: 'my-app'
})
@View({
template: '<h1 id="output">Hello, Angular 2!</h1>'
})
//#docregion class
class MyAppComponent {
}
//#enddocregion
//#enddocregion
//#docregion bootstrap
bootstrap(MyAppComponent);
//#enddocregion
//#enddocregion

View File

@ -1,17 +0,0 @@
// #docregion
function AppComponent() {}
AppComponent.annotations = [
new angular.ComponentAnnotation({
selector: 'my-app'
}),
new angular.ViewAnnotation({
template: '<h1 id="output">My first Angular 2 App</h1>'
})
];
// #docregion bootstrap
document.addEventListener('DOMContentLoaded', function() {
angular.bootstrap(AppComponent);
});
// #enddocregion

View File

@ -1,20 +0,0 @@
// protractor-spec.js
describe('Protractor quick start test', function() {
// #docregion javascript
it('should display Alice with JavaScript', function() {
browser.get('gettingstarted/js/index.html');
});
// #enddocregion
// #docregion typescript
it('should display Alice with TypeScrip', function() {
browser.get('gettingstarted/ts/index.html');
});
// #enddocregion
afterEach(function() {
expect(element(by.id('output')).getText()).toEqual('My first Angular 2 App');
});
});

View File

@ -1,15 +0,0 @@
<!-- #docregion -->
<!DOCTYPE html>
<html>
<head>
<script src="https://github.jspm.io/jmcriffey/bower-traceur-runtime@0.0.87/traceur-runtime.js"></script>
<script src="https://jspm.io/system@0.16.js"></script>
<script src="https://code.angularjs.org/2.0.0-alpha.26/angular2.dev.js"></script>
</head>
<body>
<my-app></my-app>
<script>
System.import('main');
</script>
</body>
</html>

View File

@ -1 +0,0 @@
{"version":3,"file":"main.js","sourceRoot":"","sources":["main.ts"],"names":["AppComponent","AppComponent.constructor"],"mappings":";;;;;;;;;;;AAEA,AAFA,UAAU;AACV,iBAAiB;AACjB,yBAAyC,mBAAmB,CAAC,CAAA;AAG7D,AAFA,aAAa;;IAEbA;IAOAC,CAACA;IAPDD;QAACA,oBAASA,CAACA;YACTA,QAAQA,EAAEA,QAAQA;SACnBA,CAACA;QACDA,eAAIA,CAACA;YACJA,QAAQA,EAAEA,6CAA6CA;SACxDA,CAACA;;qBAEDA;IAADA,mBAACA;AAADA,CAACA,AAPD,IAOC;AAGD,AADA,oBAAoB;AACpB,oBAAS,CAAC,YAAY,CAAC,CAAC;AACxB,aAAa"}

View File

@ -1,3 +1,4 @@
// #docplaster more code here
// #docregion import,twoparts
import {Component, View, bootstrap} from 'angular2/angular2';
// #enddocregion twoparts, import
@ -11,6 +12,11 @@ import {Component, View, bootstrap} from 'angular2/angular2';
class AppComponent {
}
// #docregion twoparts
// indented comment
var x = 3;
// plaster should go immediately under here.
// #enddocregion
// #docregion bootstrap, twoparts
bootstrap(AppComponent);
// #enddocregion twoparts

View File

@ -0,0 +1,25 @@
// #docplaster more code here
// #docregion noend,import,twoparts
import {Component, View, bootstrap} from 'angular2/angular2';
// #enddocregion twoparts, import
@Component({
selector: 'my-app'
})
@View({
template: '<h1 id="output">My first Angular 2 App</h1>'
})
class AppComponent {
}
// #docregion noend
// #docregion noend2,twoparts
// indented comment
var x = 3;
// plaster should go immediately under here.
// #enddocregion
// #docregion bootstrap, twoparts
bootstrap(AppComponent);
// #enddocregion twoparts
// to be included in bootstrap...
// #enddocregion

View File

@ -13,4 +13,4 @@ class AppComponent {
}
// #docregion bootstrap
bootstrap(AppComponent);
// #enddocregion
// #enddocregion

View File

@ -9,7 +9,6 @@
<!-- #docregion app -->
<body>
<my-app></my-app>
</body>

View File

@ -1,5 +1,5 @@
// #docregion all
// #docregion log ... everything else ignored.
// #docregion log
/**
* @description This function logs a string.
*/

View File

@ -0,0 +1,9 @@
# #docregion
name: angular2-getting-started
version: 0.0.1
dependencies:
angular2: ^2.0.0-alpha.41
browser: ^0.10.0
transformers:
- angular2:
entry_points: web/main.dart

View File

@ -1,9 +0,0 @@
// #docregion
/**
* @description This function returns a string.
*
* @returns {string} This string has the value 'Hello World'.
*/
function helloWorld() {
return 'Hello World';
}

View File

@ -1,10 +0,0 @@
// #docregion
/**
* @description This function returns a string.
*
* @returns {string} This string has the value 'Hello World'.
*/
// #docregion code2
function helloWorld() {
return 'Hello World';
}

View File

@ -1,17 +0,0 @@
<!-- #docregion -->
<!DOCTYPE html>
<html>
<head>
<!-- #docregion main -->
<script src="https://github.jspm.io/jmcriffey/bower-traceur-runtime@0.0.87/traceur-runtime.js"></script>
<script src="https://jspm.io/system@0.16.js"></script>
<script src="https://code.angularjs.org/2.0.0-alpha.26/angular2.dev.js"></script>
<!-- #enddocregion -->
</head>
<body>
<my-app></my-app>
<script>
System.import('main');
</script>
</body>
</html>

View File

@ -1,46 +0,0 @@
<h1> Frament path to jade path cross reference report
<p>Base path: c:/GitHub/angular.io.ideablade/public/doc-shredder/test</p>
<ol>
<li>
Fragment file: <strong>gettingstarted/ts/index.html</strong>
<p>Jade files</p>
<ul>
<li>test_jade/guides/setupAlt2.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/js/index.html</strong>
<p>Jade files</p>
<ul>
<li>test_jade/setupAlt.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/ts/main.ts</strong>
<p>Jade files</p>
<ul>
<li>test_jade/setupAlt.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/js/main.js</strong>
<p>Jade files</p>
<ul>
<li>test_jade/guides/setupAlt2.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/ts/main-import.ts</strong>
<p>Jade files</p>
<ul>
<li>test_jade/setupAlt.jade</li>
</ul>
<br>
</li>
</ol>

View File

@ -1,20 +0,0 @@
<h1> Jade path to fragment path cross reference report
<p>Base path: c:/GitHub/angular.io.ideablade/public/doc-shredder/test</p>
<ol>
<li>
Jade file: <strong>test_jade/guides/setupAlt2.jade</strong>
<p>Fragment files</p>
<ul><li>test_fragments/gettingstarted/ts/index.html.md</li><li>test_fragments/gettingstarted/js/index.html.md</li><li>test_fragments/gettingstarted/ts/main.ts.md</li><li>test_fragments/gettingstarted/js/main.js.md</li><li>test_fragments/gettingstarted/ts/main-import.ts.md</li>
</ul>
<br>
</li>
<li>
Jade file: <strong>test_jade/setupAlt.jade</strong>
<p>Fragment files</p>
<ul><li> *** NOT FOUND*** : test_fragments/gettingstarted/ts/index2.html.md</li><li>test_fragments/gettingstarted/js/index.html.md</li><li>test_fragments/gettingstarted/ts/main.ts.md</li><li> *** NOT FOUND*** : test_fragments/gettingstarted/js/main2.js.md</li><li>test_fragments/gettingstarted/ts/main-import.ts.md</li>
</ul>
<br>
</li>
</ol>

View File

@ -1,59 +0,0 @@
{
"basePath": "c:/GitHub/angular.io.ideablade/public/doc-shredder/test",
"jadeToFragMap": {
"test_jade/guides/setupAlt2.jade": [
{
"fragPath": "test_fragments/gettingstarted/ts/index.html.md",
"examplePath": "test_source/gettingstarted/ts/index.html",
"exists": true
},
{
"fragPath": "test_fragments/gettingstarted/js/index.html.md",
"examplePath": "test_source/gettingstarted/js/index.html",
"exists": true
},
{
"fragPath": "test_fragments/gettingstarted/ts/main.ts.md",
"examplePath": "test_source/gettingstarted/ts/main.ts",
"exists": true
},
{
"fragPath": "test_fragments/gettingstarted/js/main.js.md",
"examplePath": "test_source/gettingstarted/js/main.js",
"exists": true
},
{
"fragPath": "test_fragments/gettingstarted/ts/main-import.ts.md",
"examplePath": "test_source/gettingstarted/ts/main.ts",
"exists": true
}
],
"test_jade/setupAlt.jade": [
{
"fragPath": "test_fragments/gettingstarted/ts/index2.html.md",
"examplePath": "test_source/gettingstarted/ts/index2.html",
"exists": false
},
{
"fragPath": "test_fragments/gettingstarted/js/index.html.md",
"examplePath": "test_source/gettingstarted/js/index.html",
"exists": true
},
{
"fragPath": "test_fragments/gettingstarted/ts/main.ts.md",
"examplePath": "test_source/gettingstarted/ts/main.ts",
"exists": true
},
{
"fragPath": "test_fragments/gettingstarted/js/main2.js.md",
"examplePath": "test_source/gettingstarted/js/main2.js",
"exists": false
},
{
"fragPath": "test_fragments/gettingstarted/ts/main-import.ts.md",
"examplePath": "test_source/gettingstarted/ts/main.ts",
"exists": true
}
]
}
}

View File

@ -7,31 +7,47 @@ module.exports = function fileShredder(log, regionExtractor) {
name: 'fileShredder',
getDocs: function (fileInfo) {
var commentMarkers;
var commentInfo;
switch (fileInfo.extension) {
case 'ts':
case 'js':
case 'dart':
commentMarkers = ['//'];
commentInfo = {
prefix: '//',
blockPattern: '/* {tag} */'
};
//commentMarkers = ['//'];
break;
case 'html':
commentMarkers = ['<!--'];
commentInfo = {
prefix: '<!--',
blockPattern: '<!-- {tag} -->'
};
// commentMarkers = ['<!--'];
break;
case 'css':
commentMarkers = ['/*'];
commentInfo = {
prefix: '/*',
blockPattern: '/* {tag} */'
};
// commentMarkers = ['/*'];
break;
case 'json':
break;
case 'yaml':
commentMarkers = ['#'];
commentInfo = {
prefix: '#',
blockPattern: '# {tag} '
};
// commentMarkers = ['#'];
break;
default:
return [];
return {};
}
var docs;
// log.info("fileShredder processing: " + fileInfo.relativePath);
if (commentMarkers) {
docs = regionExtractor(fileInfo.content, commentMarkers);
if (commentInfo) {
docs = regionExtractor(fileInfo.content, commentInfo);
} else {
docs = [ { content: fileInfo.content } ];
}

View File

@ -16,19 +16,19 @@ module.exports = function regionExtractor() {
// empty enddocregion always closes last region started.
// enddocregions with names that do no match start region tags get ignored.
return function(content, commentPrefixes) {
return function(content, commentInfo) {
var lines = result = content.split(/\r?\n/);
var docStack = [];
var docStack = []; // items will be both popped and removed from the middle
var docMap = {};
var doc;
var regionNames;
var docPlaster = '. . .';
lines.forEach(function(line, ix) {
if (isCommentLine(line, commentPrefixes)) {
if (isCommentLine(line, commentInfo.prefix)) {
if (hasRegionTag(line)) {
lines[ix] = nullLine;
regionNames = getRegionNames(line);
regionNames.forEach(function(rn) {
doc = docMap[rn];
@ -69,13 +69,16 @@ module.exports = function regionExtractor() {
});
}
}
})
});
} else if (hasDocPlasterTag(line)) {
line[ix] = nullLine;
docPlaster = getDocPlaster(line);
}
}
});
var docs = _.values(docMap);
var plasterComment = docPlaster && commentInfo.blockPattern.replace('{tag}', docPlaster);
docs.forEach(function(doc) {
var content;
var fragLines = [];
@ -86,6 +89,11 @@ module.exports = function regionExtractor() {
} else {
subLines = lines.slice(range.startIx + 1);
}
if (plasterComment && fragLines.length) {
// pad is the padding on the previous line
var pad = fragLines[fragLines.length - 1].match(/(\s*)/)[0];
fragLines.push(pad + plasterComment);
}
fragLines = fragLines.concat(subLines);
});
fragLines = trimLeftIndent(fragLines);
@ -127,10 +135,8 @@ function trimLeftIndent(lines) {
return result;
}
function isCommentLine(line, commentPrefixes) {
return commentPrefixes.some(function(prefix) {
return line.trim().indexOf(prefix) == 0;
});
function isCommentLine(line, commentPrefix) {
return line.trim().indexOf(commentPrefix) == 0;
}
function hasRegionTag(line) {
@ -141,6 +147,10 @@ function hasEndRegionTag(line) {
return line.indexOf("#enddocregion") >= 0;
}
function hasDocPlasterTag(line) {
return line.indexOf("#docplaster") >= 0;
}
function getRegionNames(line) {
return extractRegionNames(line, /#docregion\s*(\S.*)/);
}
@ -149,6 +159,16 @@ function getEndRegionNames(line) {
return extractRegionNames(line, /#enddocregion\s*(\S.*)/);
}
function getDocPlaster(line) {
var rx = /#docplaster\s*(\S.*)/;
try {
var plaster = line.match(rx)[1];
return plaster.trim();
} catch (e) {
return null;
}
}
function extractRegionNames(line, rx) {
try {
var names = line.match(rx)[1];