Skip to content

Commit 2fd1624

Browse files
chalinkwalrath
authored andcommitted
chore(dart): api doc builder enhancements (angular#2050)
- angular#2049, support ng.io doc relative links and code-regions - Change dartdoc output folder to `docs/api` (from `doc/api`).
1 parent ccdc8c0 commit 2fd1624

File tree

3 files changed

+51
-15
lines changed

3 files changed

+51
-15
lines changed

gulpfile.js

+15-9
Original file line numberDiff line numberDiff line change
@@ -604,20 +604,19 @@ gulp.task('build-dart-cheatsheet', [], function() {
604604

605605
gulp.task('dartdoc', ['pub upgrade'], function() {
606606
const ngRepoPath = ngPathFor('dart');
607-
if (argv.fast && fs.existsSync(path.resolve(ngRepoPath, 'doc'))) {
608-
gutil.log('Skipping dartdoc: --fast flag enabled and "doc" dir exists');
607+
if (argv.fast && fs.existsSync(path.resolve(ngRepoPath, 'docs', 'api'))) {
608+
gutil.log('Skipping dartdoc: --fast flag enabled and "docs/api" dir exists');
609609
return true;
610610
}
611611
checkAngularProjectPath(ngRepoPath);
612612
const topLevelLibFilePath = path.resolve(ngRepoPath, 'lib', 'angular2.dart');
613613
const tmpPath = topLevelLibFilePath + '.disabled';
614-
if (!fs.existsSync(topLevelLibFilePath)) throw new Error(`Missing file: ${topLevelLibFilePath}`);
615-
fs.renameSync(topLevelLibFilePath, tmpPath);
614+
renameIfExistsSync(topLevelLibFilePath, tmpPath);
616615
gutil.log(`Hiding top-level angular2 library: ${topLevelLibFilePath}`);
617-
const dartdoc = spawnExt('dartdoc', ['--output', 'doc/api', '--add-crossdart'], { cwd: ngRepoPath});
616+
const dartdoc = spawnExt('dartdoc', ['--output', 'docs/api', '--add-crossdart'], { cwd: ngRepoPath});
618617
return dartdoc.promise.finally(() => {
619618
gutil.log(`Restoring top-level angular2 library: ${topLevelLibFilePath}`);
620-
fs.renameSync(tmpPath, topLevelLibFilePath);
619+
renameIfExistsSync(tmpPath, topLevelLibFilePath);
621620
})
622621
});
623622

@@ -1235,15 +1234,14 @@ function buildDartCheatsheet() {
12351234

12361235

12371236
function buildApiDocsForDart() {
1238-
const apiDir = 'api';
12391237
const vers = 'latest';
12401238
const dab = require('./tools/dart-api-builder/dab')(ANGULAR_IO_PROJECT_PATH);
12411239
const log = dab.log;
12421240

12431241
log.level = _dgeniLogLevel;
12441242
const dabInfo = dab.dartPkgConfigInfo;
1245-
dabInfo.ngIoDartApiDocPath = path.join(DOCS_PATH, 'dart', vers, apiDir);
1246-
dabInfo.ngDartDocPath = path.join(ngPathFor('dart'), 'doc', apiDir);
1243+
dabInfo.ngIoDartApiDocPath = path.join(DOCS_PATH, 'dart', vers, 'api');
1244+
dabInfo.ngDartDocPath = path.join(ngPathFor('dart'), 'docs', 'api');
12471245
// Exclude API entries for developer/internal libraries. Also exclude entries for
12481246
// the top-level catch all "angular2" library (otherwise every entry appears twice).
12491247
dabInfo.excludeLibRegExp = new RegExp(/^(?!angular2)|\.testing|_|codegen|^angular2$/);
@@ -1455,3 +1453,11 @@ function checkAngularProjectPath(_ngPath) {
14551453
if (fs.existsSync(ngPath)) return;
14561454
throw new Error('API related tasks require the angular2 repo to be at ' + ngPath);
14571455
}
1456+
1457+
function renameIfExistsSync(oldPath, newPath) {
1458+
if (fs.existsSync(oldPath)) {
1459+
fs.renameSync(oldPath, newPath);
1460+
} else {
1461+
gutil.log(`renameIfExistsSync cannot find file to rename: ${oldPath}`);
1462+
}
1463+
}

tools/api-builder/dart-package/test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const apiDocPath = path.join(DOCS_PATH, 'dart/latest/api');
1414

1515
dartPkg.config(function (dartPkgConfigInfo) {
1616
dartPkgConfigInfo.ngIoDartApiDocPath = apiDocPath;
17-
dartPkgConfigInfo.ngDartDocPath = path.join(ANGULAR_IO_PROJECT_PATH, '../ngdart/doc/api');
17+
dartPkgConfigInfo.ngDartDocPath = path.join(ANGULAR_IO_PROJECT_PATH, '../angular-dart/docs/api');
1818
});
1919

2020
const dgeni = new Dgeni([dartPkg]);

tools/dart-api-builder/dab.js

+35-5
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,53 @@ module.exports = function dabFactory(ngIoProjPath) {
4646
log.info(containerName, 'wrote', Object.keys(dataMap).length, 'entries to', dataFilePath);
4747
}
4848

49+
function _adjustDocsRelativeLinks($, div) {
50+
// Omit leading https://angular.io so links work for local test sites.
51+
const urlToDocs = '/docs/dart/latest/';
52+
const urlToExamples = 'http://angular-examples.github.io/';
53+
const docsLinkList = div.find('a[href^="docs/"],a[href^="examples/"]');
54+
docsLinkList.each((i, elt) => {
55+
const href = $(elt).attr('href');
56+
const matches = href.match(/(\w+)\/(.*)$/);
57+
// TODO: support links to chapters of other languages, e.g., 'docs/ts/latest/...'.
58+
const urlStart = matches[1] === 'docs' ? urlToDocs : urlToExamples;
59+
const absHref = urlStart + matches[2];
60+
log.info(`Found angular.io relative link: ${href} --> ${absHref}`);
61+
$(elt).attr('href', absHref);
62+
});
63+
}
64+
4965
function _insertExampleFragments(enclosedByName, eltId, $, div) {
50-
const fragDir = path.join(dartPkgConfigInfo.ngIoDartApiDocPath, '../../../_fragments/_api');
66+
const fragDirBase = path.join(dartPkgConfigInfo.ngIoDartApiDocPath, '../../../_fragments/');
5167
const exList = div.find('p:contains("{@example")');
5268
exList.each((i, elt) => {
5369
const text = $(elt).text();
5470
log.debug(`Found example: ${enclosedByName} ${eltId}`, text);
55-
const matches = text.match(/{@example\s+([^\s]+)(\s+region=[\'\"]?(\w+)[\'\"]?)?\s*}/);
71+
const matches = text.match(/^\s*{@example\s+([^\s]+)(\s+region=[\'\"]?([-\w]+)[\'\"]?)?\s*}([\s\S]*)$/);
5672
if (!matches) {
5773
log.warn(enclosedByName, eltId, 'has an invalidly formed @example tag:', text);
5874
return true;
5975
}
76+
// const [, exRelPath, /*regionTagAndValue*/, region, rest] = matches;
77+
const rest = matches[4].trim();
78+
if (rest) log.warn(enclosedByName, eltId, '@example must be the only element in a paragraph, but found:', text);
6079
const exRelPath = matches[1];
6180
const region = matches[3];
6281

63-
const dir = path.dirname(exRelPath)
82+
let exRelPathParts = path.dirname(exRelPath).split(path.sep);
83+
let fragDir;
84+
if (exRelPathParts[0] === 'docs') {
85+
// Path is to a docs example, not an API example.
86+
const exampleName = exRelPathParts[1];
87+
fragDir = path.join(fragDirBase, exampleName, 'dart');
88+
exRelPathParts = exRelPathParts.slice(2);
89+
} else {
90+
fragDir = path.join(fragDirBase, '_api');
91+
}
6492
const extn = path.extname(exRelPath);
6593
const baseName = path.basename(exRelPath, extn);
6694
const fileNameNoExt = baseName + (region ? `-${region}` : '')
67-
const exFragPath = path.resolve(fragDir, dir, `${fileNameNoExt}${extn}.md`);
95+
const exFragPath = path.resolve(fragDir, ...exRelPathParts, `${fileNameNoExt}${extn}.md`);
6896
if (!fs.existsSync(exFragPath)) {
6997
log.warn('Fragment not found:', exFragPath);
7098
return true;
@@ -80,7 +108,8 @@ module.exports = function dabFactory(ngIoProjPath) {
80108
function _extractAndWrapInCodeTags(md) {
81109
const lines = md.split('\n');
82110
// Drop first and last lines that are the code markdown tripple ticks (and last \n):
83-
lines.shift(); lines.pop(); lines.pop();
111+
lines.shift();
112+
while (lines && lines.pop().trim() !== '```') {}
84113
const code = lines.map((line) => encoder.htmlEncode(line)).join('\n');
85114
// TS uses format="linenums"; removing that for now.
86115
return `<code-example language="dart">${code}\n</code-example>`;
@@ -98,6 +127,7 @@ module.exports = function dabFactory(ngIoProjPath) {
98127
const div = $('div.body.container');
99128
$('div.sidebar-offcanvas-left').remove();
100129
const baseNameNoExtn = path.basename(e.path, '.html');
130+
_adjustDocsRelativeLinks($, div);
101131
_insertExampleFragments(e.enclosedByQualifiedName, baseNameNoExtn, $, div);
102132

103133
const outFileNoExtn = path.join(destDirPath, baseNameNoExtn);

0 commit comments

Comments
 (0)