squashed commits for PR 222 from jtraband

- add warning when bad example tag is encountered.
- shredding for api docs + refactoring of gulpfile to clarify task names.
- added top level gulp tasks + error handling cleanup
- added test-api-builder gulp task
- added warning messages during build-shred-map processing
- mixin signature change
- updated styleguide ... continued.
- added @exampleTabs inlinetag support + refactoring shared services between @example and @exampleTabs
- added new inline tag @linkDevGuide + cleanup
- added angular source watch logic for serve-and-sync and source for examples changed from test -> examples + cleanup
- promisify del
- styleguide explanation of @example, @exampleTabs and @linkDevGuide
This commit is contained in:
Jay Traband 2015-09-18 19:51:10 -07:00 committed by Naomi Black
parent 49496e4ce9
commit 6f6e83722e
22 changed files with 581 additions and 471 deletions

2
.gitignore vendored
View File

@ -7,4 +7,6 @@ www
.DS_Store
.idea
**/js/latest/api
public/docs/xref-*.*

View File

@ -8,6 +8,8 @@ var _ = require('lodash');
var Git = require("nodegit");
var argv = require('yargs').argv;
var Q = require("q");
// delPromise is a 'promise' version of del
var delPromise = Q.denodeify(del);
var Minimatch = require("minimatch").Minimatch;
var Dgeni = require('dgeni');
var fsExtra = require('fs-extra');
@ -16,15 +18,16 @@ var fs = fsExtra;
var docShredder = require('./public/doc-shredder/doc-shredder');
var _shredOptions = {
var _devguideShredOptions = {
examplesDir: './public/docs/_examples',
fragmentsDir: './public/docs/_fragments'
};
//var _apiShredOptions = {
// basePath: path.resolve('../angular/modules/angular2'),
// examplesDir: "test"
//}
var _apiShredOptions = {
examplesDir: '../angular/modules/angular2/examples',
fragmentsDir: './public/docs/_fragments/_api'
};
var _excludePatterns = ["**/node_modules/**", "**/typings/**"];
@ -35,52 +38,87 @@ var _excludeMatchers = _excludePatterns.map(function(excludePattern){
/*
Within this repo generated files are checked in so that we can avoid running the
shredder over the entire _examples dir each time someone refreshes the repo
( the shred-full gulp task). The gulp serve-and-watch shredder is only
( the shred-devguide-examples gulp task). The gulp serve-and-watch shredder is only
a partial shredder. It only shreds files in directories changed during
the current session.
*/
gulp.task('help', taskListing);
gulp.task('help', taskListing.withFilters(function(taskName) {
var isSubTask = taskName.substr(0,1) == "_";
return isSubTask;
}, function(taskName) {
var shouldRemove = taskName === 'default';
return shouldRemove;
}));
gulp.task('serve-and-sync', ['build-docs'], function (cb) {
gulp.task('serve-and-sync', function (cb) {
// execCommands(['harp server'], {}, cb);
execCommands(['npm run harp'], {}, cb);
var browserSync = require('browser-sync').create();
browserSync.init({
proxy: 'localhost:9000',
files: "public/docs/**/*/**/*",
files: ["public/docs/**/*/**/*" ],
logFileChanges: true,
reloadDelay: 500
});
shredWatch(_shredOptions, function() {
devGuideExamplesWatch(_devguideShredOptions, function() {
browserSync.reload();
});
apiSourceWatch(function() {
browserSync.reload();
});
});
gulp.task('serve-and-watch', function (cb) {
execCommands(['harp server'], {}, cb);
shredWatch(_shredOptions);
devGuideExamplesWatch(_devguideShredOptions);
});
gulp.task('shred-full', ['shred-clean'], function() {
return docShredder.shred( _shredOptions);
});
gulp.task('shred-clean', function(cb) {
var cleanPath = path.join(_shredOptions.fragmentsDir, '**/*.*')
del([ cleanPath, '!**/*.ovr.*'], function (err, paths) {
// console.log('Deleted files/folders:\n', paths.join('\n'));
cb();
});
});
gulp.task('build-shred-maps', ['shred-full'], function() {
gulp.task('build-docs', ['_shred-devguide-examples', 'build-api-docs'], function() {
return buildShredMaps(true);
});
gulp.task('git-changed-examples', ['shred-full'], function(){
gulp.task('build-devguide-docs', ['_shred-devguide-examples'], function() {
return buildShredMaps(true);
});
gulp.task('build-api-docs', ['_shred-api-examples'], function() {
if (!fs.existsSync('../angular')) {
throw new Error('build-api-docs task requires the angular2 repo to be at ' + path.resolve('../angular'));
}
return buildApiDocs();
});
gulp.task('_shred-devguide-examples', ['_shred-clean-devguide'], function() {
return docShredder.shred( _devguideShredOptions);
});
gulp.task('_shred-clean-devguide', function(cb) {
var cleanPath = path.join(_devguideShredOptions.fragmentsDir, '**/*.*')
return delPromise([ cleanPath, '!**/*.ovr.*', '!**/_api/**']);
});
gulp.task('_shred-api-examples', ['_shred-clean-api'], function() {
return docShredder.shred( _apiShredOptions);
});
gulp.task('_shred-clean-api', function(cb) {
var cleanPath = path.join(_apiShredOptions.fragmentsDir, '**/*.*')
return delPromise([ cleanPath, '!**/*.ovr.*' ]);
});
gulp.task('_build-shred-maps', function() {
return build-shred-maps(true);
});
gulp.task('git-changed-examples', ['_shred-devguide-examples'], function(){
var after, sha, messageSuffix;
if (argv.after) {
try {
@ -116,7 +154,7 @@ gulp.task('git-changed-examples', ['shred-full'], function(){
examplePaths = filterOutExcludedPatterns(examplePaths, _excludeMatchers);
console.log('\nExamples changed ' + messageSuffix);
console.log(examplePaths)
console.log("\nJade files and associated changed example files " + messageSuffix);
console.log("\nJade files affected by changed example files " + messageSuffix);
var jadeExampleMap = jadeShredMapToJadeExampleMap(jadeShredMap, examplePaths);
console.log(JSON.stringify(jadeExampleMap, null, " "));
console.log("-----");
@ -126,18 +164,10 @@ gulp.task('git-changed-examples', ['shred-full'], function(){
});
});
gulp.task('build-api-docs', function() {
if (!fs.existsSync('../angular')) {
throw new Error('build-api-docs task requires the angular2 repo to be at ' + path.resolve('../angular'));
}
try {
var dgeni = new Dgeni([require('./public/api-builder/angular.io-package')]);
return dgeni.generate();
} catch(err) {
console.log(err);
console.log(err.stack);
throw err;
}
gulp.task('test-api-builder', function (cb) {
execCommands(['npm run test-api-builder'], {}, cb);
});
function filterOutExcludedPatterns(fileNames, excludeMatchers) {
@ -148,12 +178,61 @@ function filterOutExcludedPatterns(fileNames, excludeMatchers) {
});
}
function apiSourceWatch(postShredAction) {
var srcPattern = ['../angular/modules/angular2/src/**/*.*'];
watch(srcPattern, function (event, done) {
console.log('Event type: ' + event.event); // added, changed, or deleted
console.log('Event path: ' + event.path); // The path of the modified file
// need to run just build
buildApiDocs().then(done);
});
var examplesPattern = ['../angular/modules/angular2/examples/**/*.*'];
watch(examplesPattern, function (event, done) {
console.log('Event type: ' + event.event); // added, changed, or deleted
console.log('Event path: ' + event.path); // The path of the modified file
// need to run shredder
var cleanPath = path.join(_apiShredOptions.fragmentsDir, '**/*.*');
return delPromise([ cleanPath, '!**/*.ovr.*' ]).then(function() {
return docShredder.shred(_apiShredOptions);
}).then(function() {
postShredAction && postShredAction();
});
});
}
function buildApiDocs() {
try {
var dgeni = new Dgeni([require('./public/api-builder/angular.io-package')]);
return dgeni.generate();
} catch(err) {
console.log(err);
console.log(err.stack);
throw err;
}
}
function devGuideExamplesWatch(shredOptions, postShredAction) {
var pattern = path.join(shredOptions.examplesDir, "**/*.*");
watch([pattern], function (event, done) {
console.log('Event type: ' + event.event); // added, changed, or deleted
console.log('Event path: ' + event.path); // The path of the modified file
docShredder.shredSingleDir(shredOptions, event.path).then(function () {
postShredAction && postShredAction();
});
});
}
function buildShredMaps(shouldWrite) {
var options = _.extend(_shredOptions, {
var options = {
devguideExamplesDir: _devguideShredOptions.examplesDir,
apiExamplesDir: _apiShredOptions.examplesDir,
fragmentsDir: _devguideShredOptions.fragmentsDir,
jadeDir: './public/docs',
outputDir: './public/docs',
writeFilesEnabled: shouldWrite
});
};
return docShredder.buildShredMap(options).then(function(docs) {
return docs;
});
@ -161,7 +240,7 @@ function buildShredMaps(shouldWrite) {
// returns a promise containing filePaths with any changed or added examples;
function getChangedExamples(sha) {
var examplesPath = _shredOptions.examplesDir;
var examplesPath = _devguideShredOptions.examplesDir;
var relativePath = path.relative(process.cwd(), examplesPath);
return Git.Repository.open(".").then(function(repo) {
if (sha.length) {
@ -177,7 +256,7 @@ function getChangedExamples(sha) {
}
function getChangedExamplesAfter(date, relativePath) {
var examplesPath = _shredOptions.examplesDir;
var examplesPath = _devguideShredOptions.examplesDir;
var relativePath = path.relative(process.cwd(), examplesPath);
return Git.Repository.open(".").then(function(repo) {
return repo.getHeadCommit();
@ -227,16 +306,7 @@ function getChangedExamplesForCommit(commit, relativePath) {
});
}
function shredWatch(shredOptions, postShredAction) {
var pattern = path.join(shredOptions.examplesDir, "**/*.*");
watch([pattern], function (event, done) {
console.log('Event type: ' + event.event); // added, changed, or deleted
console.log('Event path: ' + event.path); // The path of the modified file
docShredder.shredSingleDir(shredOptions, event.path).then(function () {
postShredAction && postShredAction();
});
});
}
function jadeShredMapToJadeExampleMap(jadeShredMap, examplePaths) {
// remove dups in examplePaths
@ -321,4 +391,4 @@ function execCommands(cmds, options, cb) {
gulp.task('default', taskListing);
gulp.task('default', ['help']);

View File

@ -6,7 +6,8 @@
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"harp": "harp server ."
"harp": "harp server .",
"test-api-builder": "jasmine-node public/api-builder"
},
"repository": {
"type": "git",
@ -22,7 +23,7 @@
"url": ""
},
"devDependencies": {
"browser-sync": "^2.8.2",
"browser-sync": "^2.9.3",
"canonical-path": "0.0.2",
"del": "^1.2.0",
"dgeni": "^0.4.0",
@ -33,11 +34,13 @@
"gulp-task-listing": "^1.0.1",
"gulp-util": "^3.0.6",
"gulp-watch": "^4.3.4",
"harp": "^0.18.0",
"html2jade": "^0.8.4",
"indent-string": "^2.1.0",
"harp": "^0.18.0",
"jasmine-core": "^2.3.4",
"karma": "^0.13.8",
"jasmine-node": "^1.14.5",
"jsonfile": "^2.2.2",
"karma": "^0.13.9",
"karma-chrome-launcher": "^0.2.0",
"karma-jasmine": "^0.3.6",
"lodash": "^3.10.1",

View File

@ -1,47 +1,67 @@
//- Mixins and associated functions
mixin makeExample(path, fileName, title, stylePatterns)
- var language = attributes.language || getExtn(fileName);
mixin makeExample(filePath, region, title, stylePatterns)
- var language = attributes.language || getExtn(filePath);
- var format = attributes.format || "linenums";
- var frag = getFrag(path, fileName);
- var frag = getFrag(filePath, region);
if (title)
.example-title #{title}
code-example(language="#{language}" format="#{format}")
!= styleString(frag, stylePatterns)
mixin makeTabs(path, fileNames, tabNames, stylePatterns)
- fileNames = fileNames.split(",");
- tabNames = tabNames.split(",")
mixin makeTabs(filePaths, regions, tabNames, stylePatterns)
- filePaths = strSplit(filePaths);
- regions = strSplit(regions, filePaths.length);
- tabNames = strSplit(tabNames, filePaths.length);
code-tabs
each fileName,index in fileNames
each filePath,index in filePaths
- var region = regions[index].trim();
- var tabName = tabNames[index].trim();
- var fileName = fileNames[index].trim();
- var language = attributes.language || getExtn(fileName);
- var language = attributes.language || getExtn(filePath);
- var format = attributes.format || "linenums";
- var frag = getFrag(path, fileName);
- var frag = getFrag(filePath, region);
- var sps = Array.isArray(stylePatterns) ? stylePatterns[index] : stylePatterns;
code-pane(language="#{language}" name="#{tabName}" format="#{format}")
!= styleString(frag, sps)
mixin makeJson(path, fileName, title, jsonConfig, stylePatterns)
- var language = attributes.language || getExtn(fileName);
mixin makeJson( filePath, jsonConfig, title, stylePatterns)
- var language = attributes.language || getExtn(filePath);
- var format = attributes.format || "linenums";
- var frag = getFrag(path, fileName);
- var frag = getFrag(filePath, '');
- var json = unescapeHtml(frag);
- var jsonExtract = extractJson(json, jsonConfig);
if (title)
.example-title #{title}
code-example(language="#{language}" format="#{format}")
!= styleString(jsonExtract, stylePatterns)
if (jsonExtract == 'ERROR')
err ERROR: Unable to extract json using config: "#{jsonConfig.toString()}"
else
!= styleString(jsonExtract, stylePatterns)
//---------------------------------------------------------------------------------------------------------
- var getFrag = function(path, fileName) {
- var fullFileName = getPathToFrags() + path + "/" + fileName + '.md';
- var EMPTY_STRINGS = [ '','','','','','',''];
- var strSplit = function(str, length) {
- var res;
- str = str || '';
- if (!length) {
- res = str.split(",");
- } else {
- res = str.split(",");
- if (res.length < length) {
- res = res.concat(EMPTY_STRINGS.slice(0, length - res.length));
- }
- }
- return res;
- }
- var getFrag = function(filePath, region) {
- var fullFileName = getFragFilePath(filePath, region);
- var frag = partial(fullFileName);
- if (frag == null) {
- return "BAD FILENAME: " + fullFileName + " Current path: " + current.path + " PathToDocs: " + getPathToDocs();
@ -56,10 +76,15 @@ mixin makeJson(path, fileName, title, jsonConfig, stylePatterns)
- }
- var extractJson = function(json, jsonConfig ) {
- if (jsonConfig) {
- return extractJsonFragment(json, jsonConfig.rootPath || null, jsonConfig.paths || [], jsonConfig.space || " ");
- } else {
- return json;
- try {
- if (jsonConfig) {
- return extractJsonFragment(json, jsonConfig.rootPath || null, jsonConfig.paths || [], jsonConfig.space || " ");
- } else {
- return json;
- }
- } catch (e) {
- return "ERROR";
- // return json;
- }
- }
@ -81,6 +106,15 @@ mixin makeJson(path, fileName, title, jsonConfig, stylePatterns)
- return source;
- }
- var getFragFilePath = function (filePath, region) {
- filePath = filePath.trim();
- var extn = getExtn(filePath);
- var fileBase = filePath.substr(0,filePath.length - (extn.length + 1));
- var regionPad = (region && region.length) ? '-' + region.toString() : '';
- var fullFileName = getPathToFrags() + fileBase + regionPad + "." + extn + '.md';
- return fullFileName;
- }
//- styles a string according to a regular expression.
//- The match groups resulting from the regexp application are what is styled
//- (not the whole regexp).

View File

@ -2,16 +2,10 @@ var path = require('canonical-path');
var Package = require('dgeni').Package;
var basePackage = require('../docs-package');
// MIGRATION: removed these vars
// var PARTIAL_PATH = 'partials';
// var MODULES_DOCS_PATH = PARTIAL_PATH + '/api';
module.exports = new Package('angular.io', [basePackage])
.factory(require('./services/renderMarkdown'))
.processor(require('./processors/addJadeDataDocsProcessor'))
// MIGRATION: added packageInfo to point to angular/angular repo
// overrides base packageInfo and returns the one for the 'angular/angular' repo.
.factory(require('./services/packageInfo'))
@ -33,7 +27,7 @@ module.exports = new Package('angular.io', [basePackage])
];
readTypeScriptModules.hidePrivateMembers = true;
// MIGRATION: HACK - readFileProcessor.basePath set to point to a local repo location
// HACK - readFileProcessor.basePath set to point to a local repo location
// because the docs-package-processor will
// have previously set it to point to angular/angular repo.
// needed because the writeFilesProcessor uses the readFilesProcessor's basePath.
@ -61,24 +55,18 @@ module.exports = new Package('angular.io', [basePackage])
getPath: function computeModulePath(doc) {
return doc.id.replace(/^angular2\//, '');
},
// MIGRATION:
// outputPathTemplate: MODULES_DOCS_PATH + '/${id}/index.jade'
outputPathTemplate: '${path}/index.jade'
});
computePathsProcessor.pathTemplates.push({
docTypes: EXPORT_DOC_TYPES,
pathTemplate: '${moduleDoc.path}/${name}-${docType}.html',
// MIGRATION:
// outputPathTemplate: MODULES_DOCS_PATH + '/${moduleDoc.id}/${name}-${docType}.jade',
outputPathTemplate:'${moduleDoc.path}/${name}-${docType}.jade',
});
computePathsProcessor.pathTemplates.push({
docTypes: ['jade-data'],
pathTemplate: '${originalDoc.path}/_data',
// MIGRATION:
// outputPathTemplate: MODULES_DOCS_PATH + '/${path}.json'
outputPathTemplate: '${path}.json'
});
})

View File

@ -33,9 +33,9 @@ module.exports = new Package('angular-v2-docs', [jsdocPackage, nunjucksPackage,
// Configure file reading
.config(function(readFilesProcessor, ngdocFileReader, readTypeScriptModules) {
readFilesProcessor.fileReaders = [ngdocFileReader];
// MIGRATION: set the readFilesProcessor base path to point to angular repo.
// set the readFilesProcessor base path to point to angular repo.
var angular_repo_path = path.resolve(__dirname, '../../../../angular');
// TODO: confirm that the angular repo is actually there.
// confirm that the angular repo is actually there.
if (!fs.existsSync(angular_repo_path)) {
throw new Error('build-api-docs task requires the angular2 repo to be at ' + angular_repo_path);
}

View File

@ -3,12 +3,18 @@ var Package = require('dgeni').Package;
module.exports = new Package('links', [])
.factory(require('./inline-tag-defs/link'))
.factory(require('./inline-tag-defs/linkDevGuide'))
.factory(require('./inline-tag-defs/example'))
.factory(require('./inline-tag-defs/exampleTabs'))
.factory(require('dgeni-packages/ngdoc/services/getAliases'))
.factory(require('dgeni-packages/ngdoc/services/getDocFromAlias'))
.factory(require('./services/getLinkInfo'))
.factory(require('./services/parseArgString'))
.factory(require('./services/getApiFragmentFileName'))
.config(function(inlineTagProcessor, linkInlineTagDef, exampleInlineTagDef) {
.config(function(inlineTagProcessor, linkInlineTagDef, linkDevGuideInlineTagDef, exampleInlineTagDef, exampleTabsInlineTagDef) {
inlineTagProcessor.inlineTagDefinitions.push(linkInlineTagDef);
inlineTagProcessor.inlineTagDefinitions.push(linkDevGuideInlineTagDef);
inlineTagProcessor.inlineTagDefinitions.push(exampleInlineTagDef);
inlineTagProcessor.inlineTagDefinitions.push(exampleTabsInlineTagDef);
});

View File

@ -1,44 +1,52 @@
var path = require('canonical-path');
var fs = require("fs");
/**
* @dgService exampleInlineTagDef
* @description
* Process inline example tags (of the form {@example relativePath region -title='some title' -stylePattern='{some style pattern}' }),
* replacing them with a jade makeExample mixin call.
* Examples:
* {@example core/application_spec.ts hello-app -title='Sample component' }
* {@example core/application_spec.ts -region=hello-app -title='Sample component' }
* @kind function
* @param {Object} path The relative path to example
* @param {Function} docs error message
* @return {String} The jade makeExample mixin call
*
* @property {boolean} relativeLinks Whether we expect the links to be relative to the originating doc
*/
module.exports = function exampleInlineTagDef(getLinkInfo, createDocMessage, log) {
module.exports = function exampleInlineTagDef(getLinkInfo, parseArgString, getApiFragmentFileName, createDocMessage, log) {
return {
name: 'example',
description: 'Process inline example tags (of the form {@example some/uri Some Title}), replacing them with HTML anchors',
handler: function(doc, tagName, tagDescription) {
var tagArgs = parseArgs(tagDescription);
var tagArgs = parseArgString(tagDescription);
var unnamedArgs = tagArgs._;
var relativePath = unnamedArgs[0];
var region = unnamedArgs.length > 1 && unnamedArgs[1];
var title = tagArgs.title;
var mixinFilePath = path.join('_api', relativePath);
var region = tagArgs.region || (unnamedArgs.length > 1 ? unnamedArgs[1] : null);
var title = tagArgs.title || (unnamedArgs.length > 2 ? unnamedArgs[2] : null );
// TODO: not yet implemented here
var stylePattern = tagArgs.stylePattern;
var dir = path.join("_api", path.dirname(relativePath));
var extn = path.extname(relativePath);
var baseNameNoExtn = path.basename(relativePath, extn);
var baseName = region ? baseNameNoExtn + "-" + region + extn : baseNameNoExtn + extn;
// check if fragment file actually exists.
var fragFileName = getApiFragmentFileName(relativePath, region);
if ( !fs.existsSync(fragFileName)) {
log.warn(createDocMessage('Invalid example (unable to locate fragment file: ' + quote(fragFileName) + ")", doc));
}
var comma = ', '
var res = [ "+makeExample(", quote(dir), comma, quote(baseName), comma, title ? quote(title) : 'null', ")" ].join('');
var res = [ "+makeExample(", quote(mixinFilePath), comma, region ? quote(region) : 'null', comma, title ? quote(title) : 'null', ")" ].join('');
return res;
}
};
};
// Examples of what @example and @exampleTabs markup looks like in the angular/angular source.
//*
//* {@example core/application_spec.ts hello-app -title='Sample component' }
//*
//* {@exampleTabs core/application_spec.ts,core/application_spec.ts "hello-app,hello-app2" -titles="Hello app1, Hello app2" }
//*
function quote(str) {
if (str == null || str.length === 0) return str;
str = str.replace("'","'\'");
@ -46,47 +54,3 @@ function quote(str) {
}
// processes an arg string in 'almost' the same fashion that the command processor does
// and returns an args object in yargs format.
function parseArgs(str) {
// regex from npm string-argv
//[^\s'"] Match if not a space ' or "
//+|['] or Match '
//([^']*) Match anything that is not '
//['] Close match if '
//+|["] or Match "
//([^"]*) Match anything that is not "
//["] Close match if "
var rx = /[^\s'"]+|[']([^']*?)[']|["]([^"]*?)["]/gi;
var value = str;
var unnammedArgs = [];
var args = { _: unnammedArgs };
var match, key;
do {
//Each call to exec returns the next regex match as an array
match = rx.exec(value);
if (match !== null) {
//Index 1 in the array is the captured group if it exists
//Index 0 is the matched text, which we use if no captured group exists
var arg = match[2] ? match[2] : (match[1]?match[1]:match[0]);
if (key) {
args[key] = arg;
key = null;
} else {
if (arg.substr(arg.length-1) === '=') {
key = arg.substr(0, arg.length-1);
// remove leading '-' if it exists.
if (key.substr(0,1)=='-') {
key = key.substr(1);
}
} else {
unnammedArgs.push(arg)
key = null;
}
}
}
} while (match !== null);
return args;
}

View File

@ -0,0 +1,56 @@
var path = require('canonical-path');
var fs = require("fs");
/**
* @dgService exampleTabsInlineTagDef
* @description
* Process inline example tags (of the form {@example relativePath region -title='some title' -stylePattern='{some style pattern}' }),
* replacing them with a jade makeExample mixin call.
* Examples:
* {@exampleTabs core/application_spec.ts,core/application_spec.ts "hello-app,hello-app2" -titles="Hello app1, Hello app2" }
* {@exampleTabs core/application_spec.ts,core/application_spec.ts regions="hello-app,hello-app2" -titles="Hello app1, Hello app2" }
* @kind function
*/
module.exports = function exampleTabsInlineTagDef(getLinkInfo, parseArgString, getApiFragmentFileName, createDocMessage, log) {
return {
name: 'exampleTabs',
description: 'Process inline example tags (of the form {@example some/uri Some Title}), replacing them with HTML anchors',
handler: function(doc, tagName, tagDescription) {
var tagArgs = parseArgString(tagDescription);
var unnamedArgs = tagArgs._;
var relativePaths = unnamedArgs[0].split(',');
var regions = tagArgs.regions || (unnamedArgs.length > 1 ? unnamedArgs[1] : null);
var titles = tagArgs.titles || (unnamedArgs.length > 2 ? unnamedArgs[2] : null);
if (regions) {
regions = regions.split(',');
}
// TODO: not yet implemented here
var stylePatterns = tagArgs.stylePattern;
var mixinPaths = relativePaths.map(function(relativePath, ix) {
var fragFileName = getApiFragmentFileName(relativePath, regions && regions[ix]);
if ( !fs.existsSync(fragFileName)) {
log.warn(createDocMessage('Invalid example (unable to locate fragment file: ' + quote(fragFileName) + ")", doc));
}
return path.join('_api', relativePath);
});
var comma = ', '
var pathsArg = quote(mixinPaths.join(','));
var regionsArg = regions ? quote(regions.join(',')) : 'null';
var titlesArg = titles ? quote(titles) : 'null';
var res = [ "+makeTabs(", pathsArg, comma, regionsArg, comma, titlesArg, ")" ].join('');
return res;
}
};
};
function quote(str) {
if (str == null || str.length === 0) return str;
str = str.replace("'","'\'");
return "'" + str + "'";
}

View File

@ -0,0 +1,53 @@
var path = require('canonical-path');
var fs = require("fs");
var jsonFile = require('jsonFile');
var INLINE_LINK = /(\S+)(?:\s+([\s\S]+))?/;
/**
* @dgService linkDevGuideInlineTagDef
* @description
* Process inline link tags (of the form {@linkDevGuide some/uri 'Some Title'}), replacing them with HTML anchors.
* The uri should point to a jade page in the DevGuide without the .jade extension ( under public/docs ).
* If the title is omitted an attempt will be made to determine the title of the jade page being pointed to. If not found
* the the title will simply be the last part of the link.
* Examples
* {@linkDevGuide ts/latest/guide/gettingStarted }
* {@linkDevGuide js/latest/guide/gettingStarted 'Javascript version of getting started' }
* {@linkDevGuide ts/latest/guide/gettingStarted title="Typescript version of getting started" }
* @kind function
*/
module.exports = function linkDevGuideInlineTagDef(parseArgString, createDocMessage, log) {
return {
name: 'linkDevGuide',
description: 'Process inline link tags (of the form {@link some/uri "Some Title"}), replacing them with HTML anchors',
handler: function(doc, tagName, tagDescription) {
// Parse out the uri and title
var tagArgs = parseArgString(tagDescription);
var unnamedArgs = tagArgs._;
var uri = unnamedArgs[0];
var title = tagArgs.title || (unnamedArgs.length > 1 ? unnamedArgs[1] : null);
var jadePath = path.join('./public/docs', uri + '.jade');
var key = path.basename(jadePath, '.jade');
if ( !fs.existsSync(jadePath)) {
log.warn(createDocMessage('Invalid DevGuide example (unable to locate jade file: "' + jadePath + '")', doc));
} else {
if (!title) {
var jsonFilePath = path.join(path.dirname(jadePath), '_data.json');
if ( fs.existsSync(jsonFilePath)) {
var jsonObj = jsonFile.readFileSync(jsonFilePath);
title = jsonObj[key] && jsonObj[key].title;
}
}
}
var url = path.join('/docs', uri + '.html');
title = title || key || url;
return "<a href='" + url + "'>" + title + "</a>";
}
};
};

View File

@ -0,0 +1,25 @@
var path = require('canonical-path');
var FRAGMENT_DIR = "./public/docs/_fragments";
/**
* @dgService getApiFragmentFileName
* @description
* returns the name of the api fragment file given a relative path and a region tag.
* @kind function
* @param {String} relativePath The relative path to the example file some part of which will be pulled in.
* @param {String} region Name of a region within this file ( may be null).
* @return {Object} The api fragment file name
* @return {Object} The api fragment file name
*/
module.exports = function getApiFragmentFileName() {
return function getApiFragmentFileName(relativePath, region) {
var dir = path.join("_api", path.dirname(relativePath));
var extn = path.extname(relativePath);
var baseNameNoExtn = path.basename(relativePath, extn);
var fileName = region ? baseNameNoExtn + "-" + region + extn : baseNameNoExtn + extn;
var fragFileName = path.join(FRAGMENT_DIR, dir, fileName + '.md');
return fragFileName;
}
}

View File

@ -0,0 +1,55 @@
/**
* @dgService parseArgString
* @description
* processes an arg string in 'almost' the same fashion that the command processor does
* and returns an args object in yargs format.
* @kind function
* @param {String} str The arg string to process
* @return {Object} The args parsed into a yargs format.
*/
module.exports = function parseArgString() {
return function parseArgStringImpl(str) {
// regex from npm string-argv
//[^\s'"] Match if not a space ' or "
//+|['] or Match '
//([^']*) Match anything that is not '
//['] Close match if '
//+|["] or Match "
//([^"]*) Match anything that is not "
//["] Close match if "
var rx = /[^\s'"]+|[']([^']*?)[']|["]([^"]*?)["]/gi;
var value = str;
var unnammedArgs = [];
var args = {_: unnammedArgs};
var match, key;
do {
//Each call to exec returns the next regex match as an array
match = rx.exec(value);
if (match !== null) {
//Index 1 in the array is the captured group if it exists
//Index 0 is the matched text, which we use if no captured group exists
var arg = match[2] ? match[2] : (match[1] ? match[1] : match[0]);
if (key) {
args[key] = arg;
key = null;
} else {
if (arg.substr(arg.length - 1) === '=') {
key = arg.substr(0, arg.length - 1);
// remove leading '-' if it exists.
if (key.substr(0, 1) == '-') {
key = key.substr(1);
}
} else {
unnammedArgs.push(arg)
key = null;
}
}
}
} while (match !== null);
return args;
}
}

View File

@ -197,15 +197,11 @@ function resolveShredOptions(shredOptions) {
function resolveMapOptions(mapOptions) {
var so = _.defaults({}, mapOptions, {
// read files from any subdir under here
jadeDir: "./docs",
fragmentsDir: "./docs/_fragments",
examplesDir: "./docs/_examples",
// whether to include subdirectories when shredding.
includeSubdirs: true
});
so.jadeDir = path.resolve(so.jadeDir);
so.examplesDir = path.resolve(so.examplesDir);
so.devguideExamplesDir = path.resolve(so.devguideExamplesDir);
so.apiExamplesDir = path.resolve(so.apiExamplesDir);
so.fragmentsDir = path.resolve(so.fragmentsDir);
return so;
}

View File

@ -7,24 +7,26 @@ var path = require('canonical-path');
module.exports = function extractPathsReader(log) {
// regex for makeTabs line
var rx = /\s*\+make(?:=Tabs|Example)\(\s*["'](.*?)["']\s*,\s*["'](.*?)["'].*?\)/g
var rx = /\s*\+make(?:=Tabs|Example|Json)\(\s*["'](.*?)["']\s*,\s*["'](.*?)["'].*?\)/g
return {
name: 'extractPathsReader',
// returns the fragment filePath without the _fragments dir on the front or the '.md'
getDocs: function (fileInfo) {
var content = fileInfo.content;
var fragPaths = [];
var fragItems = [];
var r;
while ((r = rx.exec(content)) !== null) {
var basePath = r[1];
var fileNames = r[2].split(',');
fileNames.forEach(function(fn) {
fragPaths.push(path.join(basePath, fn.trim()));
})
var filePaths = r[1].split(',');
var regions = (r.length > 2) ? r[2].split(",") : null;
filePaths.forEach(function(filePath, ix) {
var region = regions && regions[ix];
fragItems.push( { mixinPath: filePath, region: region } );
});
}
if (fragPaths.length) {
if (fragItems.length) {
return [{
fragPaths: fragPaths
fragItems: fragItems
}];
} else {
return [];

View File

@ -24,12 +24,17 @@ module.exports = function fileShredder(log, regionExtractor) {
default:
return [];
}
log.info("fileShredder processing: " + fileInfo.relativePath);
var docs;
// log.info("fileShredder processing: " + fileInfo.relativePath);
if (commentMarkers) {
return regionExtractor(fileInfo.content, commentMarkers);
docs = regionExtractor(fileInfo.content, commentMarkers);
} else {
return [ { content: fileInfo.content } ];
docs = [ { content: fileInfo.content } ];
}
if (docs.length) {
log.info("shredded file: " + fileInfo.relativePath);
}
return docs;
}
}
}

View File

@ -7,7 +7,7 @@ var path = require('canonical-path');
var fs = require('fs');
var _ = require('lodash');
module.exports = function shredMapProcessor(log) {
module.exports = function shredMapProcessor(log, createDocMessage) {
return {
$runAfter: ['readFilesProcessor'],
$runBefore: ['rendering-docs'],
@ -20,10 +20,22 @@ module.exports = function shredMapProcessor(log) {
docs.forEach(function(doc) {
var jadePath = path.join(options.jadeDir, doc.fileInfo.relativePath);
var fragInfoSet = {};
doc.fragPaths.forEach(function(fragPath) {
var fullFragPath = path.join(options.fragmentsDir, fragPath) + '.md';
var examplePath = getExampleName(fragPath);
var fullExamplePath = path.join(options.examplesDir, examplePath);
doc.fragItems.forEach(function(fragItem) {
var mixinPath = fragItem.mixinPath;
var fullExamplePath;
if ( mixinPath.indexOf('_api') >= 0) {
var sourcePath = mixinPath.replace('_api/','');
fullExamplePath = path.join(options.apiExamplesDir, sourcePath);
} else {
fullExamplePath = path.join(options.devguideExamplesDir, mixinPath);
}
var region = fragItem.region ? "-" + fragItem.region : '';
var extn = path.extname(mixinPath);
var basename = path.basename(mixinPath, extn);
var fragDir = path.dirname(mixinPath);
var fragPath = path.join(fragDir, basename + region + extn) + '.md';
var fullFragPath = path.join(options.fragmentsDir, fragPath);
var fragInfo = { fragPath: fullFragPath, examplePath: fullExamplePath, exists: fs.existsSync(fullFragPath) };
fragInfoSet[fragPath] = fragInfo;
if (fragInfo.exists) {
@ -33,6 +45,9 @@ module.exports = function shredMapProcessor(log) {
fragToJadeMap[fragPath] = jadePathsSet;
}
jadePathsSet[jadePath] = jadePath;
} else {
var relativePath = path.relative(".", fullFragPath);
log.warn(createDocMessage('Invalid example (unable to locate fragment file: "' + relativePath + '")', doc));
}
});
jadeToFragMap[jadePath] = _.values(fragInfoSet);

View File

@ -19,14 +19,14 @@ include ../../../_includes/_util-fns
of the documentation. These examples will each typically consist of a collection of html, javascript and css files.
Clearly there also needs to be some mechanism for including fragments of these files into the jade/harp generated
html. By convention all of the 'testable' examples within this repository should be created within the `docs\_examples` folder.
html. By convention all of the 'testable' examples within this repository should be created within the `docs/_examples` folder.
To include an example from somewhere in the `doc\_examples` folder you can use the `makeExample` mixin.
To include an example from somewhere in the `doc/_examples` folder you can use the `makeExample` mixin.
This mixin along with the `makeTabs` mixin both require that the 'included' file be marked
up with special comment markers. This markup will be described a bit later.
In addition there are several custom gulp tasks that must be run before any of the edits described below. These
gulp tasks are documented elsewhere.
In addition there are several custom gulp tasks that must be run before any of the edits described below will actually appear
in the generated documentation. These gulp tasks are documented elsewhere.
In order to use the `makeExample` or `makeTabs` mixins each page that references the mixins must include the '_utilFns.jade'
file on the current page. This is usually accomplished simply by adding a path to this file at the top of any
@ -38,43 +38,45 @@ include ../../../_includes/_util-fns
:markdown
The syntax for the `makeExample` mixin is:
#### +makeExample(basePath, filePath, title, stylePattern)
- *basePath:* base path under '_examples'
- *filePath:* will be combined with the base path to locate the actual file
- *title:* title displayed above the included text.
- *stylePattern:* (*optional) allows additional styling via regular expression ( described later).
#### +makeExample(filePath, region, title, stylePattern)
- *filePath:* path to the example file under the '_examples' folder
- *region:* (optional or null) region from the example file to display
- *title:* (optional or null) title displayed above the included text.
- *stylePattern:* (optional or null) allows additional styling via regular expression ( described later).
#### Example:
code-example(format="linenums" language="js").
+makeExample('styleguide', 'js/index.html', 'index.html')
+makeExample('styleguide/js/index.html', null, 'index.html')
:markdown
This will read the *_examples/styleguide/js/index.html* file and include it
with the heading 'index.html'. Note that the file will be properly escaped and
color coded according to the extension on the file ( html in this case).
+makeExample('styleguide', 'js/index.html', 'index.html')
+makeExample('styleguide/js/index.html', null, 'index.html')
:markdown
The second parameter with a value of 'null' will be described later in this document.
There is a similar `makeTabs` mixin that provides the same service but for multiple examples
within a tabbed interface.
#### +makeTabs(basePath, filePaths, titles, stylePatterns)
- *basePath:* base path under '_examples'
- *filePaths:* a comma delimited string of paths that will each be combined with the base path to locate the actual file
- *titles:* a comma delimited string of titles corresponding to each of the filePaths above.
- *stylePatterns:* (*optional) allows additional styling via regular expression( described later).
#### +makeTabs(filePaths, regions, titles, stylePatterns)
- *filePaths:* a comma delimited string of filePaths to example files under the '_examples' folder
- *regions:* (optional or null) region from the example file to display
- *titles:* (optional or null) a comma delimited string of titles corresponding to each of the filePaths above.
- *stylePatterns:* (optional or null) allows additional styling via regular expression( described later).
#### Example:
code-example(format="linenums" language="js").
+makeTabs('styleguide', 'js/index.html, js/spec.js', 'index.html,unit test')
+makeTabs('styleguide/js/index.html, styleguide/js/spec.js', null, 'index.html,unit test')
:markdown
This will create two tabs, each with its own title and appropriately color coded.
+makeTabs('styleguide', 'js/index.html, js/spec.js', 'index.html,unit test')
+makeTabs('styleguide/js/index.html, styleguide/js/spec.js', null, 'index.html,unit test')
.l-sub-section
:markdown
@ -152,19 +154,17 @@ include ../../../_includes/_util-fns
### Including a named #docregion via the makeExample or makeTabs mixins.
In order to include just a portion of an example file that has been marked up with a 'named' `#docregion`
you will pass in an 'extended' file name that indicates the name of both the file and the region.
An extended file name is simply the file name with the name of the file suffixed with a "-" followed by the
name of the region. So a a file `foo.js` with a "test" region would have an extended file name of `foo-test.js`.
you will pass the name of the desired region as the 2nd parameter to the makeExample call.
#### Example
code-example(format="linenums" language="js").
+makeExample('styleguide', 'js/app-class-w-annotations.js')
+makeExample('styleguide/js/app.js', 'class-w-annotations', "Extracted region")
:markdown
is a request to include just the `class-w-annotations` region from the `app.js` file in the `_examples/styleguide`
folder and results in the following:
+makeExample('styleguide', 'js/app-class-w-annotations.js')
+makeExample('styleguide/js/app.js', 'class-w-annotations', "Extracted region")
.l-sub-section
:markdown
@ -184,7 +184,7 @@ include ../../../_includes/_util-fns
#### Example
code-example(format="linenums" language="js" escape="none").
+makeExample('styleguide', 'js/index.html', 'index.html', { pnk: /script (src=.*&ampquot)/g })
+makeExample('styleguide/js/index.html', null, 'index.html', {pnk: /script (src=.*&ampquot)/g})
:markdown
Which will mark all of the quoted contents of each `script` tag within the index.html file in pink.
@ -193,20 +193,20 @@ include ../../../_includes/_util-fns
Note that expression replacement occurs AFTER the fragment has been included and html escaped.
This means that your regular expression must use escaped html text; i.e. the '&ampquot' in the regex above.
+makeExample('styleguide', 'js/index.html', 'index.html', {pnk: /script (src=.*&quot)/g})
+makeExample('styleguide/js/index.html', null, 'index.html', {pnk: /script (src=.*&quot)/g})
:markdown
A more complicated example might be:
code-example(format="linenums" language="js").
- var stylePattern = { pnk: /script (src=.*&ampquot;)/g, otl: /(\S*my-app.*$)/m };
+makeExample('styleguide', 'js/index.html', 'index.html', stylePattern )
+makeExample('styleguide/js/index.html', null, 'index.html', stylePattern )
:markdown
Which applies multiple styles and uses an intermediate javascript object as opposed to a literal.
- var stylePattern = { pnk: /script (src=.*&quot;)/g, otl: /(\S*my-app.*$)/m };
+makeExample('styleguide', 'js/index.html', 'index.html', stylePattern )
+makeExample('styleguide/js/index.html', null, 'index.html', stylePattern )
:markdown
`makeTabs` support for `stylePatterns` is slightly different from the `makeExample` mixin in that you can also
@ -215,10 +215,10 @@ include ../../../_includes/_util-fns
code-example(format="linenums" language="js").
-var stylePatterns = [{ pnk: /script (src=.*&ampquot;)/g }, {pnk: /(result)/ }];
+makeTabs('styleguide', 'js/index.html, js/spec.js', 'index.html,unit test', stylePatterns)
+makeTabs('styleguide/js/index.html, styleguide/js/spec.js', null, 'index.html,unit test', stylePatterns)
-var stylePatterns = [{ pnk: /script (src=.*&quot;)/g }, {pnk: /(result)/ }];
+makeTabs('styleguide', 'js/index.html, js/spec.js', 'index.html,unit test', stylePatterns)
+makeTabs('styleguide/js/index.html, styleguide/js/spec.js', null, 'index.html,unit test', stylePatterns)
.l-sub-section
:markdown
@ -230,49 +230,48 @@ include ../../../_includes/_util-fns
The `makeJson` mixin does however provide a similar capability to selectively pick which portions of the '.json' file
to display.
The syntax for the `makeExample` mixin is:
The syntax for the `makeJson` mixin is:
#### +makeExample(basePath, filePath, title, jsonConfig, stylePattern)
- *basePath:* base path under '_examples'
- *filePath:* will be combined with the base path to locate the actual file
- *title:* (optional) title displayed above the included text.
#### +makeJson(filePath, jsonConfig, title, stylePattern)
- *filePath:* path to the example file under the '_examples' folder
- *jsonConfig:* (optional) an object that defines which portions of the .json file to select for display.
- *rootPath:* (optional default=null) a json property path at which the 'paths' parameter below should start.
- *paths:* a comma delimited list of property paths for those elements to be selected.
- *space:* (optional default=" " [2 spaces]) a String or Number object that's used to insert white space into the output JSON
- *title:* (optional) title displayed above the included text.
- *stylePattern:* (*optional) allows additional styling via regular expression ( described above).
#### Example:
code-example(format="linenums" language="js").
+makeJson('styleguide', 'package.json', "Entire package.json file")
+makeJson('styleguide/package.json', null, "Entire package.json file")
+makeJson('styleguide', 'package.json', "Entire package.json file")
+makeJson('styleguide/package.json', null, "Entire package.json file")
:markdown
A subset of the '.json' file can also be selected.
code-example(format="linenums" language="js").
+makeJson('styleguide', 'package.json', "Selected parts of the package.json file", {paths: 'version, scripts.tsc, scripts.start '} )
+makeJson('styleguide/package.json', { paths: 'version, scripts.tsc, scripts.start '}, "Selected parts of the package.json file" )
+makeJson('styleguide', 'package.json', "Selected parts of the package.json file", {paths: 'version, scripts.tsc, scripts.start '} )
+makeJson('styleguide/package.json', { paths: 'version, scripts.tsc, scripts.start '}, "Selected parts of the package.json file" )
:markdown
Styling selected portions of the json is also supported.
code-example(format="linenums" language="js").
+makeJson('styleguide', 'package.json', "package.json dependencies", {paths: 'dependencies'}, { pnk: [/(\S*traceur.*)/, /(\Sangular2.*)/, /(\Ssystem.*)/ ]})
+makeJson('styleguide/package.json', {paths: 'dependencies'}, "package.json dependencies", { pnk: [/(\S*traceur.*)/, /(\Sangular2.*)/, /(\Ssystem.*)/ ]})
+makeJson('styleguide', 'package.json', "package.json dependencies", {paths: 'dependencies'}, { pnk: [/(\S*traceur.*)/, /(\Sangular2.*)/, /(\Ssystem.*)/ ]})
+makeJson('styleguide/package.json', {paths: 'dependencies'}, "package.json dependencies", { pnk: [/(\S*traceur.*)/, /(\Sangular2.*)/, /(\Ssystem.*)/ ]})
:markdown
As well as styling across multiple lines.
code-example(format="linenums" language="js").
+makeJson('styleguide', 'package.json', "Foo", {paths: 'name, version, dependencies '}, styles )
+makeJson('styleguide/package.json', {paths: 'name, version, dependencies '}, "Foo", styles )
- var styles = { pnk: /(^.*dependencies[\s\S]* \})/gm };
+makeJson('styleguide', 'package.json', "Foo", {paths: 'name, version, dependencies '}, styles )
+makeJson('styleguide/package.json', {paths: 'name, version, dependencies '}, "Foo", styles )
.l-sub-section
:markdown
@ -372,17 +371,92 @@ include ../../../_includes/_util-fns
#### Example
code-example().
+makeExample('styleguide', 'js/app-class-w-annotations.js')(format="linenums:15")
+makeExample('styleguide/js/app.js', "class-w-annotations")(format="linenums:15")
:markdown
Starts the numbering of the example at line 15.
+makeExample('styleguide', 'js/app-class-w-annotations.js')(format="linenums:15")
+makeExample('styleguide/js/app.js', "class-w-annotations")(format="linenums:15")
:markdown
Or to supress line numbering completely you can use
Or to suppress line numbering completely you can use
code-example().
+makeExample('styleguide', 'js/app-class-w-annotations.js')(format=".")
+makeExample('styleguide/js/app.js', 'class-w-annotations')(format=".")
+makeExample('styleguide', 'js/app-class-w-annotations.js')(format=".")
+makeExample('styleguide/js/app.js', 'class-w-annotations')(format=".")
.l-sub-section
:markdown
### Code examples in angular/angular source code
References to embedded example code in the angular/angular source make use of the same mixins as defined above, but with a slightly different
syntax. Inline tags in source code comments like {@example ...} and {@exampleTabs ...} actually generate 'makeExample' and 'makeTabs' mixins
calls in the documentation. The order of 'arguments' in the inline tags is also the same as that of the mixins defined above. However, optional
parameters can also be specified via name (optionally prefixed with a '-'), as will be shown by example below. Parameters that include spaces should
be enclosed in either single or double quotes. This syntax is intended to mirror standard command line argument patterns.
.alert.is-important.
The '@example' and '@exampleTabs' inline tags MUST always appear at the beginning of a line.
Example files referenced by inline tags are all assumed to be in the 'modules/angular2' folder in the angular/angular repo.
:markdown
#### @example inline tag parameters
- *filePath:* path to the example file under the '_examples' folder
- *region:* (optional or null) region from the example file to display
- *title:* (optional or null) title displayed above the included text.
- *stylePattern:* (optional or null) allows additional styling via regular expression ( described later).
#### Examples
code-example(format="linenums" language="js").
/**
* An example with no region
* {@example core/directives/ng_if_spec.ts -title='Whole other component' }
*
* An example with a region and a title both specified by name
* {@example core/directives/ng_if_spec.ts region='ng-if' title='Partial' }
*
* Another example with a region and a title with only the title specified explicitly.
* {@example core/directives/ng_if_spec.ts foo title='Foo' }
**/
:markdown
#### @exampleTabs inline tag parameters
- *filePaths:* a comma delimited string of filePaths to example files under the '_examples' folder
- *regions:* (optional or null) region from the example file to display
- *titles:* (optional or null) a comma delimited string of titles corresponding to each of the filePaths above.
- *stylePatterns:* (optional or null) allows additional styling via regular expression( described later).
#### Examples
code-example(format="linenums" language="js").
/**
* An example with multiple tabs each with its own region and title.
* {@exampleTabs core/directives/test1_spec.ts,core/directives/test2_spec.ts regions='aaa,bbb,' -titles='Test 1,Test 2' }
*
**/
.l-sub-section
:markdown
### Cross references to Developer guide pages in angular/angular source comments.
The '{@linkDevGuide ... }' inline tag is intended to be used to create links from api documentation to dev guide
documentation.
#### @linkDevGuide inline tag parameters
- *filePath:* a filePath that points to a jade page in the DevGuide without the .jade extension ( under public/docs ).
- *title:* The title of link. If the title is omitted an attempt will be made to determine the title of the jade page
being pointed to. If not found the then title will simply be the link.
#### Examples
code-example(format="linenums" language="js").
/**
* An link to the Developer guide example with a link title
* This can appear anywhere in a comment line: {@linkDevGuide /js/latest/guide/gettingStarted 'Getting Started' }
* and the same link can also be expressed with an explicit 'title' param
* {@linkDevGuide /js/latest/guide/gettingStarted title='Getting Started' }
* Or... an attempt will be made to infer the title if it is omitted.
* {@linkDevGuide /js/latest/guide/gettingStarted }
**/

View File

@ -28,7 +28,7 @@ include ../../../../_includes/_util-fns
:markdown
Then add a new `index.html` file to the project folder and enter the following HTML
+makeExample('gettingstarted', 'js/index.html', 'index.html')(format="")
+makeExample('gettingstarted/js/index.html', null, 'index.html')(format="")
.l-sub-section
:markdown
@ -48,7 +48,7 @@ include ../../../../_includes/_util-fns
Create an *app.js* file with the following content:
+makeExample('gettingstarted', 'js/app-class-w-annotations.js')
+makeExample('gettingstarted/js/app.js', 'class-w-annotations')
:markdown
When we step back and squint, we see that
@ -64,7 +64,7 @@ include ../../../../_includes/_util-fns
The **`Component`** method tells Angular that this is a component
controlling the element named "my-app".
+makeExample('gettingstarted', 'js/app-component.js')
+makeExample('gettingstarted/js/app.js', 'component')
:markdown
You may remember we added such an element to our *index.html* above.
@ -72,7 +72,7 @@ include ../../../../_includes/_util-fns
The **`View`** method identifies the HTML template
that defines the visual appearance of the component.
+makeExample('gettingstarted', 'js/app-view.js')
+makeExample('gettingstarted/js/app.js', 'view')
:markdown
We're writing the HTML template inline
@ -84,7 +84,7 @@ include ../../../../_includes/_util-fns
giving it properties and methods that bind to the view and whatever
behavior is appropriate for this part of the UI.
+makeExample('gettingstarted', 'js/app-class.js')
+makeExample('gettingstarted/js/app.js', 'class')
:markdown
This component has the minimum implementation:

View File

@ -144,7 +144,7 @@ include ../../../../_includes/_util-fns
Add a new `index.html` file to the project folder and enter the following HTML
+makeExample('gettingstarted', 'ts/src/index.html', 'index.html')
+makeExample('gettingstarted/ts/src/index.html', null, 'index.html')
.l-sub-section
:markdown
@ -163,7 +163,7 @@ include ../../../../_includes/_util-fns
Create an *app.ts* file and add an empty class called `AppComponent` as follows:
+makeExample('gettingstarted', 'ts/src/app-class.ts')
+makeExample('gettingstarted/ts/src/app.ts', 'class')
:markdown
We won't ask this class to do anything. It's just an empty, meaningless class until we tell
@ -171,13 +171,13 @@ include ../../../../_includes/_util-fns
We import the `component` and `view` *annotations* that we need from the Angular library at the top of the file:
+makeExample('gettingstarted', 'ts/src/app-import.ts')
+makeExample('gettingstarted/ts/src/app.ts', 'import')
:markdown
Then we apply those annotations to the `AppComponent` class by writing the following lines
just above the class definition:
+makeExample('gettingstarted', 'ts/src/app-class-w-annotations.ts')
+makeExample('gettingstarted/ts/src/app.ts', 'class-w-annotations')
.l-sub-section
:markdown
@ -201,12 +201,12 @@ include ../../../../_includes/_util-fns
with an instance of the `AppComponent` class as the root component.
We call this "bootstrapping the app".
+makeExample('gettingstarted', 'ts/src/app-bootstrap.ts')
+makeExample('gettingstarted/ts/src/app.ts', 'bootstrap')
:markdown
Here is the complete *app.ts*
+makeExample('gettingstarted', 'ts/src/app.ts', 'app.ts')
+makeExample('gettingstarted/ts/src/app.ts', null, 'app.ts')
.l-main-section

View File

@ -1,109 +0,0 @@
<h1> Frament path to jade path cross reference report
<ol>
<li>
Fragment file: <strong>styleguide/js/index.html</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/_includes/styleguide/_code-examples.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>styleguide/js/app-class-w-annotations.js</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/_includes/styleguide/_code-examples.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/js/index.html</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/js/latest/guide/gettingStarted.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/js/app-class-w-annotations.js</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/js/latest/guide/gettingStarted.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/js/app-component.js</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/js/latest/guide/gettingStarted.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/js/app-view.js</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/js/latest/guide/gettingStarted.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/js/app-class.js</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/js/latest/guide/gettingStarted.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/ts/src/index.html</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/ts/latest/guide/gettingStarted.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/ts/src/app-class.ts</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/ts/latest/guide/gettingStarted.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/ts/src/app-import.ts</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/ts/latest/guide/gettingStarted.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/ts/src/app-class-w-annotations.ts</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/ts/latest/guide/gettingStarted.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/ts/src/app-bootstrap.ts</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/ts/latest/guide/gettingStarted.jade</li>
</ul>
<br>
</li>
<li>
Fragment file: <strong>gettingstarted/ts/src/app.ts</strong>
<p>Jade files</p>
<ul>
<li>C:/GitHub/angular.io.ideablade/public/docs/ts/latest/guide/gettingStarted.jade</li>
</ul>
<br>
</li>
</ol>

View File

@ -1,40 +0,0 @@
<h1> Jade path to fragment path cross reference report
<ol>
<li>
Jade file: <strong>C:/GitHub/angular.io.ideablade/public/docs/_includes/styleguide/_code-examples.jade</strong>
<p>Fragment files</p>
<ul><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/styleguide/js/index.html.md</li><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/styleguide/js/app-class-w-annotations.js.md</li>
</ul>
<br>
</li>
<li>
Jade file: <strong>C:/GitHub/angular.io.ideablade/public/docs/js/latest/api/core/APP_COMPONENT-const.jade</strong>
<p>Fragment files</p>
<ul><li> *** NOT FOUND*** : C:/GitHub/angular.io.ideablade/public/docs/_fragments/_api/a.b-foo.c.md</li>
</ul>
<br>
</li>
<li>
Jade file: <strong>C:/GitHub/angular.io.ideablade/public/docs/js/latest/api/core/ComponentMetadata-class.jade</strong>
<p>Fragment files</p>
<ul><li> *** NOT FOUND*** : C:/GitHub/angular.io.ideablade/public/docs/_fragments/_api/a.b-foo.c.md</li>
</ul>
<br>
</li>
<li>
Jade file: <strong>C:/GitHub/angular.io.ideablade/public/docs/js/latest/guide/gettingStarted.jade</strong>
<p>Fragment files</p>
<ul><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/js/index.html.md</li><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/js/app-class-w-annotations.js.md</li><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/js/app-component.js.md</li><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/js/app-view.js.md</li><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/js/app-class.js.md</li>
</ul>
<br>
</li>
<li>
Jade file: <strong>C:/GitHub/angular.io.ideablade/public/docs/ts/latest/guide/gettingStarted.jade</strong>
<p>Fragment files</p>
<ul><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/index.html.md</li><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/app-class.ts.md</li><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/app-import.ts.md</li><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/app-class-w-annotations.ts.md</li><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/app-bootstrap.ts.md</li><li>C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/app.ts.md</li>
</ul>
<br>
</li>
</ol>

View File

@ -1,89 +0,0 @@
{
"jadeToFragMap": {
"C:/GitHub/angular.io.ideablade/public/docs/_includes/styleguide/_code-examples.jade": [
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/styleguide/js/index.html.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/styleguide/js/index.html",
"exists": true
},
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/styleguide/js/app-class-w-annotations.js.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/styleguide/js/app-class-w.js",
"exists": true
}
],
"C:/GitHub/angular.io.ideablade/public/docs/js/latest/api/core/APP_COMPONENT-const.jade": [
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/_api/a.b-foo.c.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/_api/a.b-foo.c",
"exists": false
}
],
"C:/GitHub/angular.io.ideablade/public/docs/js/latest/api/core/ComponentMetadata-class.jade": [
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/_api/a.b-foo.c.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/_api/a.b-foo.c",
"exists": false
}
],
"C:/GitHub/angular.io.ideablade/public/docs/js/latest/guide/gettingStarted.jade": [
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/js/index.html.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/gettingstarted/js/index.html",
"exists": true
},
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/js/app-class-w-annotations.js.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/gettingstarted/js/app-class-w.js",
"exists": true
},
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/js/app-component.js.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/gettingstarted/js/app.js",
"exists": true
},
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/js/app-view.js.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/gettingstarted/js/app.js",
"exists": true
},
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/js/app-class.js.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/gettingstarted/js/app.js",
"exists": true
}
],
"C:/GitHub/angular.io.ideablade/public/docs/ts/latest/guide/gettingStarted.jade": [
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/index.html.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/gettingstarted/ts/src/index.html",
"exists": true
},
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/app-class.ts.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/gettingstarted/ts/src/app.ts",
"exists": true
},
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/app-import.ts.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/gettingstarted/ts/src/app.ts",
"exists": true
},
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/app-class-w-annotations.ts.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/gettingstarted/ts/src/app-class-w.ts",
"exists": true
},
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/app-bootstrap.ts.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/gettingstarted/ts/src/app.ts",
"exists": true
},
{
"fragPath": "C:/GitHub/angular.io.ideablade/public/docs/_fragments/gettingstarted/ts/src/app.ts.md",
"examplePath": "C:/GitHub/angular.io.ideablade/public/docs/_examples/gettingstarted/ts/src/app.ts",
"exists": true
}
]
}
}