chore(dart): api doc builder enhancements (#2050)

- #2049, support ng.io doc relative links and code-regions
- Change dartdoc output folder to `docs/api` (from `doc/api`).
This commit is contained in:
Patrice Chalin 2016-08-10 10:36:23 -07:00 committed by Kathy Walrath
parent ccdc8c0cec
commit 2fd162425d
3 changed files with 51 additions and 15 deletions

View File

@ -604,20 +604,19 @@ gulp.task('build-dart-cheatsheet', [], function() {
gulp.task('dartdoc', ['pub upgrade'], function() {
const ngRepoPath = ngPathFor('dart');
if (argv.fast && fs.existsSync(path.resolve(ngRepoPath, 'doc'))) {
gutil.log('Skipping dartdoc: --fast flag enabled and "doc" dir exists');
if (argv.fast && fs.existsSync(path.resolve(ngRepoPath, 'docs', 'api'))) {
gutil.log('Skipping dartdoc: --fast flag enabled and "docs/api" dir exists');
return true;
}
checkAngularProjectPath(ngRepoPath);
const topLevelLibFilePath = path.resolve(ngRepoPath, 'lib', 'angular2.dart');
const tmpPath = topLevelLibFilePath + '.disabled';
if (!fs.existsSync(topLevelLibFilePath)) throw new Error(`Missing file: ${topLevelLibFilePath}`);
fs.renameSync(topLevelLibFilePath, tmpPath);
renameIfExistsSync(topLevelLibFilePath, tmpPath);
gutil.log(`Hiding top-level angular2 library: ${topLevelLibFilePath}`);
const dartdoc = spawnExt('dartdoc', ['--output', 'doc/api', '--add-crossdart'], { cwd: ngRepoPath});
const dartdoc = spawnExt('dartdoc', ['--output', 'docs/api', '--add-crossdart'], { cwd: ngRepoPath});
return dartdoc.promise.finally(() => {
gutil.log(`Restoring top-level angular2 library: ${topLevelLibFilePath}`);
fs.renameSync(tmpPath, topLevelLibFilePath);
renameIfExistsSync(tmpPath, topLevelLibFilePath);
})
});
@ -1235,15 +1234,14 @@ function buildDartCheatsheet() {
function buildApiDocsForDart() {
const apiDir = 'api';
const vers = 'latest';
const dab = require('./tools/dart-api-builder/dab')(ANGULAR_IO_PROJECT_PATH);
const log = dab.log;
log.level = _dgeniLogLevel;
const dabInfo = dab.dartPkgConfigInfo;
dabInfo.ngIoDartApiDocPath = path.join(DOCS_PATH, 'dart', vers, apiDir);
dabInfo.ngDartDocPath = path.join(ngPathFor('dart'), 'doc', apiDir);
dabInfo.ngIoDartApiDocPath = path.join(DOCS_PATH, 'dart', vers, 'api');
dabInfo.ngDartDocPath = path.join(ngPathFor('dart'), 'docs', 'api');
// Exclude API entries for developer/internal libraries. Also exclude entries for
// the top-level catch all "angular2" library (otherwise every entry appears twice).
dabInfo.excludeLibRegExp = new RegExp(/^(?!angular2)|\.testing|_|codegen|^angular2$/);
@ -1455,3 +1453,11 @@ function checkAngularProjectPath(_ngPath) {
if (fs.existsSync(ngPath)) return;
throw new Error('API related tasks require the angular2 repo to be at ' + ngPath);
}
function renameIfExistsSync(oldPath, newPath) {
if (fs.existsSync(oldPath)) {
fs.renameSync(oldPath, newPath);
} else {
gutil.log(`renameIfExistsSync cannot find file to rename: ${oldPath}`);
}
}

View File

@ -14,7 +14,7 @@ const apiDocPath = path.join(DOCS_PATH, 'dart/latest/api');
dartPkg.config(function (dartPkgConfigInfo) {
dartPkgConfigInfo.ngIoDartApiDocPath = apiDocPath;
dartPkgConfigInfo.ngDartDocPath = path.join(ANGULAR_IO_PROJECT_PATH, '../ngdart/doc/api');
dartPkgConfigInfo.ngDartDocPath = path.join(ANGULAR_IO_PROJECT_PATH, '../angular-dart/docs/api');
});
const dgeni = new Dgeni([dartPkg]);

View File

@ -46,25 +46,53 @@ module.exports = function dabFactory(ngIoProjPath) {
log.info(containerName, 'wrote', Object.keys(dataMap).length, 'entries to', dataFilePath);
}
function _adjustDocsRelativeLinks($, div) {
// Omit leading https://angular.io so links work for local test sites.
const urlToDocs = '/docs/dart/latest/';
const urlToExamples = 'http://angular-examples.github.io/';
const docsLinkList = div.find('a[href^="docs/"],a[href^="examples/"]');
docsLinkList.each((i, elt) => {
const href = $(elt).attr('href');
const matches = href.match(/(\w+)\/(.*)$/);
// TODO: support links to chapters of other languages, e.g., 'docs/ts/latest/...'.
const urlStart = matches[1] === 'docs' ? urlToDocs : urlToExamples;
const absHref = urlStart + matches[2];
log.info(`Found angular.io relative link: ${href} --> ${absHref}`);
$(elt).attr('href', absHref);
});
}
function _insertExampleFragments(enclosedByName, eltId, $, div) {
const fragDir = path.join(dartPkgConfigInfo.ngIoDartApiDocPath, '../../../_fragments/_api');
const fragDirBase = path.join(dartPkgConfigInfo.ngIoDartApiDocPath, '../../../_fragments/');
const exList = div.find('p:contains("{@example")');
exList.each((i, elt) => {
const text = $(elt).text();
log.debug(`Found example: ${enclosedByName} ${eltId}`, text);
const matches = text.match(/{@example\s+([^\s]+)(\s+region=[\'\"]?(\w+)[\'\"]?)?\s*}/);
const matches = text.match(/^\s*{@example\s+([^\s]+)(\s+region=[\'\"]?([-\w]+)[\'\"]?)?\s*}([\s\S]*)$/);
if (!matches) {
log.warn(enclosedByName, eltId, 'has an invalidly formed @example tag:', text);
return true;
}
// const [, exRelPath, /*regionTagAndValue*/, region, rest] = matches;
const rest = matches[4].trim();
if (rest) log.warn(enclosedByName, eltId, '@example must be the only element in a paragraph, but found:', text);
const exRelPath = matches[1];
const region = matches[3];
const dir = path.dirname(exRelPath)
let exRelPathParts = path.dirname(exRelPath).split(path.sep);
let fragDir;
if (exRelPathParts[0] === 'docs') {
// Path is to a docs example, not an API example.
const exampleName = exRelPathParts[1];
fragDir = path.join(fragDirBase, exampleName, 'dart');
exRelPathParts = exRelPathParts.slice(2);
} else {
fragDir = path.join(fragDirBase, '_api');
}
const extn = path.extname(exRelPath);
const baseName = path.basename(exRelPath, extn);
const fileNameNoExt = baseName + (region ? `-${region}` : '')
const exFragPath = path.resolve(fragDir, dir, `${fileNameNoExt}${extn}.md`);
const exFragPath = path.resolve(fragDir, ...exRelPathParts, `${fileNameNoExt}${extn}.md`);
if (!fs.existsSync(exFragPath)) {
log.warn('Fragment not found:', exFragPath);
return true;
@ -80,7 +108,8 @@ module.exports = function dabFactory(ngIoProjPath) {
function _extractAndWrapInCodeTags(md) {
const lines = md.split('\n');
// Drop first and last lines that are the code markdown tripple ticks (and last \n):
lines.shift(); lines.pop(); lines.pop();
lines.shift();
while (lines && lines.pop().trim() !== '```') {}
const code = lines.map((line) => encoder.htmlEncode(line)).join('\n');
// TS uses format="linenums"; removing that for now.
return `<code-example language="dart">${code}\n</code-example>`;
@ -98,6 +127,7 @@ module.exports = function dabFactory(ngIoProjPath) {
const div = $('div.body.container');
$('div.sidebar-offcanvas-left').remove();
const baseNameNoExtn = path.basename(e.path, '.html');
_adjustDocsRelativeLinks($, div);
_insertExampleFragments(e.enclosedByQualifiedName, baseNameNoExtn, $, div);
const outFileNoExtn = path.join(destDirPath, baseNameNoExtn);