Bunch of dartdoc changes:

- Add special fake entrypoints so you can build docs for just corelib,
  dom, or html.
- Better main index page.
- Only show classes in nav for current library.
- Link to index page.
- Fix word wrap on icons.
- Sort case-insensitively.

Review URL: http://codereview.chromium.org//8822001

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@2143 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
rnystrom@google.com 2011-12-06 21:20:34 +00:00
parent 5a23450f9c
commit cbbae74150
5 changed files with 118 additions and 71 deletions

View file

@ -4,9 +4,22 @@
# .dart file, like:
#
# $ dartdoc foo.dart
#
# You can also pass in a couple of "special" entrypoints for generating
# docs for dart's built in libraries. The special entrypoints are:
#
# - "corelib": dart:core, dart:coreimpl
# - "dom": dart:core, dart:coreimpl, dart:dom
# - "html": dart:core, dart:coreimpl, dart:dom, dart:html
# Get the .dart lib file the user wants to generate docs for.
entrypoint=$PWD/$1
# Add the path to it so that we can find it, but only if it's a .dart file and
# not one of the special fake entrypoints like "corelib".
entrypoint=$1
if [[ $1 == *.dart ]]
then
entrypoint=$PWD/$1
fi
# Run from dartdoc directory to get correct relative paths.
pushd `dirname "$0"` >>/dev/null

View file

@ -30,8 +30,8 @@ final corePath = 'lib';
/** Path to generate html files into. */
final outdir = 'docs';
/** Set to `true` to include the source code in the generated docs. */
bool includeSource = false;
/** Set to `false` to not include the source code in the generated docs. */
bool includeSource = true;
/** Special comment position used to store the library-level doc comment. */
final _libraryDoc = -1;
@ -63,7 +63,7 @@ int _totalMembers = 0;
*/
void main() {
// The entrypoint of the library to generate docs for.
final libPath = process.argv[2];
final entrypoint = process.argv[2];
// Parse the dartdoc options.
for (int i = 3; i < process.argv.length; i++) {
@ -80,6 +80,7 @@ void main() {
files = new NodeFileSystem();
parseOptions('../../frog', [] /* args */, files);
options.dietParse = true;
// Patch in support for [:...:]-style code to the markdown parser.
// TODO(rnystrom): Markdown already has syntax for this. Phase this out?
@ -93,15 +94,41 @@ void main() {
initializeWorld(files);
world.processDartScript(libPath);
// Handle the built-in entrypoints.
switch (entrypoint) {
case 'corelib':
world.getOrAddLibrary('dart:core');
world.getOrAddLibrary('dart:coreimpl');
world.process();
break;
case 'dom':
world.getOrAddLibrary('dart:core');
world.getOrAddLibrary('dart:coreimpl');
world.getOrAddLibrary('dart:dom');
world.process();
break;
case 'html':
world.getOrAddLibrary('dart:core');
world.getOrAddLibrary('dart:coreimpl');
world.getOrAddLibrary('dart:dom');
world.getOrAddLibrary('dart:html');
world.process();
break;
default:
// Normal entrypoint script.
world.processDartScript(entrypoint);
}
world.resolveAll();
// Generate the docs.
docIndex();
for (final library in world.libraries.getValues()) {
docLibrary(library);
}
docIndex(world.libraries.getValues());
});
print('Documented $_totalLibraries libraries, $_totalTypes types, and ' +
@ -112,40 +139,6 @@ void initializeDartDoc() {
_comments = <String, Map<int, String>>{};
}
docIndex(List<Library> libraries) {
startFile('index.html');
// TODO(rnystrom): Need to figure out what this should look like.
writeln(
'''
<html><head>
<title>Index</title>
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body>
<div class="content">
<ul>
''');
final sorted = new List<Library>.from(libraries);
sorted.sort((a, b) => a.name.compareTo(b.name));
for (final library in sorted) {
writeln(
'''
<li>${a(libraryUrl(library), "Library ${library.name}")}</li>
''');
}
writeln(
'''
</ul>
</div>
</body></html>
''');
endFile();
}
writeHeader(String title) {
writeln(
'''
@ -175,15 +168,34 @@ writeFooter() {
''');
}
docIndex() {
startFile('index.html');
writeHeader('Dart Documentation');
writeln('<h1>Dart Documentation</h1>');
writeln('<h3>Libraries</h3>');
for (final library in orderByName(world.libraries)) {
writeln(
'''
<h4>${a(libraryUrl(library), "Library ${library.name}")}</h4>
''');
}
writeFooter();
endFile();
}
docNavigation() {
writeln(
'''
<div class="nav">
<h1>Libraries</h1>
<h1>${a("index.html", "Dart Documentation")}</h1>
''');
for (final library in orderValuesByKeys(world.libraries)) {
write('<h2><div class="icon-library"></div> ');
for (final library in orderByName(world.libraries)) {
write('<h2><div class="icon-library"></div>');
if ((_currentLibrary == library) && (_currentType == null)) {
write('<strong>${library.name}</strong>');
@ -192,32 +204,36 @@ docNavigation() {
}
write('</h2>');
final types = orderValuesByKeys(library.types);
if (types.length > 0) {
writeln('<ul>');
for (final type in types) {
if (type.isTop) continue;
if (type.name.startsWith('_')) continue;
var icon = type.isClass ? 'icon-class' : 'icon-interface';
write('<li><div class="$icon"></div> ');
if (_currentType == type) {
write('<strong>${type.name}</strong>');
} else {
write('${a(typeUrl(type), type.name)}');
}
writeln('</li>');
}
writeln('</ul>');
}
// Only expand classes in navigation for current library.
if (_currentLibrary == library) docLibraryNavigation(library);
}
writeln('</div>');
}
/** Writes the navigation for the types contained by the given library. */
docLibraryNavigation(Library library) {
final types = orderByName(library.types).filter(
(type) => !type.isTop && !type.name.startsWith('_'));
if (types.length == 0) return;
writeln('<ul>');
for (final type in types) {
var icon = type.isClass ? 'icon-class' : 'icon-interface';
write('<li><div class="$icon"></div>');
if (_currentType == type) {
write('<strong>${typeName(type)}</strong>');
} else {
write('${a(typeUrl(type), typeName(type))}');
}
writeln('</li>');
}
writeln('</ul>');
}
docLibrary(Library library) {
_totalLibraries++;
_currentLibrary = library;
@ -237,10 +253,9 @@ docLibrary(Library library) {
// Document the top-level members.
docMembers(library.topType);
// TODO(rnystrom): Link to types.
writeln('<h3>Types</h3>');
for (final type in orderValuesByKeys(library.types)) {
for (final type in orderByName(library.types)) {
if (type.isTop) continue;
if (type.name.startsWith('_')) continue;
writeln(
@ -292,7 +307,7 @@ void docMembers(Type type) {
final methods = [];
final fields = [];
for (final member in orderValuesByKeys(type.members)) {
for (final member in orderByName(type.members)) {
if (member.name.startsWith('_')) continue;
if (member.isProperty) {

View file

@ -11,6 +11,11 @@ main() {
window.on.contentLoaded.add((e) {
for (var elem in document.queryAll('.method, .field')) {
var showCode = elem.query('.show-code');
// Skip it if we don't have a code link. Will happen if source code is
// disabled.
if (showCode == null) continue;
var pre = elem.query('pre.source');
showCode.on.click.add((e) {
if (pre.classes.contains('expanded')) {

View file

@ -107,7 +107,7 @@ hr + h2 {
.nav h2 {
font: 400 16px/22px 'Open Sans', 'Lucida Sans Unicode', 'Lucida Grande',
sans-serif;
margin: 22px -21px 0 -21px;
margin: 0 -21px;
padding: 11px 22px;
/* Using http://www.colorzilla.com/gradient-editor/ */
@ -124,9 +124,11 @@ hr + h2 {
font: 600 13px/22px 'Open Sans', 'Lucida Sans Unicode', 'Lucida Grande',
sans-serif;
list-style-type: none;
white-space: nowrap;
}
.nav ul {
margin: 0 0 22px 0;
padding: 0;
}
@ -135,7 +137,7 @@ hr + h2 {
display: inline-block;
width: 12px;
height: 13px;
margin: 4px 8px 0 2px;
margin: 5px 11px 0 3px;
vertical-align: top;
}
@ -152,7 +154,7 @@ hr + h2 {
width: 16px;
height: 14px;
display: inline-block;
margin: 4px 4px 0 0;
margin: 4px 8px 0 0;
vertical-align: top;
}

View file

@ -54,3 +54,15 @@ String unindent(String text, int indentation) {
return text.substring(start);
}
/** Sorts the map by the key, doing a case-insensitive comparison. */
List orderByName(Map<String, Dynamic> map) {
// TODO(rnystrom): it'd be nice to have this in corelib.
List keys = map.getKeys();
keys.sort((x, y) => x.toUpperCase().compareTo(y.toUpperCase()));
final values = [];
for (var k in keys) {
values.add(map[k]);
}
return values;
}