feat(ngdocs): added functionality to import and extract contents of external files inside docs comment code

This commit is contained in:
Matias Niemelä 2013-04-02 18:20:33 -04:00 committed by Misko Hevery
parent 0b6f1ce5f8
commit 2845dd1590
3 changed files with 64 additions and 19 deletions

View file

@ -8,6 +8,8 @@ var htmlEscape = require('./dom.js').htmlEscape;
var Example = require('./example.js').Example;
var NEW_LINE = /\n\r?/;
var globalID = 0;
var fs = require('fs');
var fspath = require('path');
exports.trim = trim;
exports.metadata = metadata;
@ -113,6 +115,19 @@ Doc.prototype = {
return id;
}
function extractInlineDocCode(text, tag) {
if(tag == 'all') {
//use a greedy operator to match the last </docs> tag
regex = /\/\/<docs.*?>([.\s\S]+)\/\/<\/docs>/im;
}
else {
//use a non-greedy operator to match the next </docs> tag
regex = new RegExp("\/\/<docs\\s*tag=\"" + tag + "\".*?>([.\\s\\S]+?)\/\/<\/docs>","im");
}
var matches = regex.exec(text.toString());
return matches && matches.length > 1 ? matches[1] : "";
}
parts.forEach(function(text, i) {
parts[i] = (text || '').
replace(/<example(?:\s+module="([^"]*)")?(?:\s+deps="([^"]*)")?>([\s\S]*?)<\/example>/gmi, function(_, module, deps, content) {
@ -123,8 +138,30 @@ Doc.prototype = {
content.replace(/<file\s+name="([^"]*)"\s*>([\s\S]*?)<\/file>/gmi, function(_, name, content) {
example.addSource(name, content);
});
content.replace(/<file\s+src="([^"]+)"(?:\s+tag="([^"]+)")?(?:\s+name="([^"]+)")?\s*\/?>/gmi, function(_, file, tag, name) {
if(fspath.existsSync(file)) {
var content = fs.readFileSync(file, 'utf8');
if(content && content.length > 0) {
if(tag && tag.length > 0) {
content = extractInlineDocCode(content, tag);
}
name = name && name.length > 0 ? name : fspath.basename(file);
example.addSource(name, content);
}
}
return '';
})
return placeholder(example.toHtml());
}).
replace(/(?:\*\s+)?<file.+?src="([^"]+)"(?:\s+tag="([^"]+)")?\s*\/?>/i, function(_, file, tag) {
if(fspath.existsSync(file)) {
var content = fs.readFileSync(file, 'utf8');
if(tag && tag.length > 0) {
content = extractInlineDocCode(content, tag);
}
return content;
}
}).
replace(/^<doc:example(\s+[^>]*)?>([\s\S]*)<\/doc:example>/mi, function(_, attrs, content) {
var html, script, scenario,
example = new Example(self.scenarios);

View file

@ -83,25 +83,7 @@ function $RootScopeProvider(){
*
* Here is a simple scope snippet to show how you can interact with the scope.
* <pre>
angular.injector(['ng']).invoke(function($rootScope) {
var scope = $rootScope.$new();
scope.salutation = 'Hello';
scope.name = 'World';
expect(scope.greeting).toEqual(undefined);
scope.$watch('name', function() {
scope.greeting = scope.salutation + ' ' + scope.name + '!';
}); // initialize the watch
expect(scope.greeting).toEqual(undefined);
scope.name = 'Misko';
// still old value, since watches have not been called yet
expect(scope.greeting).toEqual(undefined);
scope.$digest(); // fire all the watches
expect(scope.greeting).toEqual('Hello Misko!');
});
* <file src="./test/ng/rootScopeSpec.js" tag="docs1" />
* </pre>
*
* # Inheritance

View file

@ -1114,4 +1114,30 @@ describe('Scope', function() {
});
});
});
describe("doc examples", function() {
it("should properly fire off watch listeners upon scope changes", inject(function($rootScope) {
//<docs tag="docs1">
var scope = $rootScope.$new();
scope.salutation = 'Hello';
scope.name = 'World';
expect(scope.greeting).toEqual(undefined);
scope.$watch('name', function() {
scope.greeting = scope.salutation + ' ' + scope.name + '!';
}); // initialize the watch
expect(scope.greeting).toEqual(undefined);
scope.name = 'Misko';
// still old value, since watches have not been called yet
expect(scope.greeting).toEqual(undefined);
scope.$digest(); // fire all the watches
expect(scope.greeting).toEqual('Hello Misko!');
//</docs>
}));
});
});