Skip to content

Dartdoc customization #1005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions app/lib/dartdoc/customization.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:io';

import 'package:html/dom.dart';
import 'package:html/parser.dart' as html_parser;

class DartdocCustomizer {
final String packageName;
final String packageVersion;

DartdocCustomizer(this.packageName, this.packageVersion);

Future<bool> customizeDir(String path) async {
bool changed = false;
final dir = new Directory(path);
await for (var fse in dir.list(recursive: true)) {
if (fse is File && fse.path.endsWith('.html')) {
final c = await customizeFile(fse);
changed = changed || c;
}
}
return changed;
}

Future<bool> customizeFile(File file) async {
final String oldContent = await file.readAsString();
final String newContent = customizeHtml(oldContent);
if (newContent != null && oldContent != newContent) {
await file.writeAsString(newContent);
return true;
} else {
return false;
}
}

String customizeHtml(String html) {
final doc = html_parser.parse(html);
final breadcrumbs = doc.body.querySelector('.breadcrumbs');
if (breadcrumbs != null) {
_addPubSiteLogo(breadcrumbs);
_addPubPackageLink(breadcrumbs);
}
return doc.outerHtml;
}

void _addPubSiteLogo(Element breadcrumbs) {
final parent = breadcrumbs.parent;
final logoLink = new Element.tag('a');
logoLink.attributes['href'] = 'https://pub.dartlang.org/';
final imgRef = new Element.tag('img');
imgRef.attributes['src'] =
'https://pub.dartlang.org/static/img/dart-logo.svg';
imgRef.attributes['style'] = 'height: 30px; margin-right: 1em;';
logoLink.append(imgRef);
parent.insertBefore(logoLink, breadcrumbs);
parent.insertBefore(new Text('\n '), breadcrumbs);
}

void _addPubPackageLink(Element breadcrumbs) {
final pubPackageLink =
'https://pub.dartlang.org/packages/$packageName/versions/$packageVersion';
final pubPackageText = '$packageName package';
if (breadcrumbs.children.length == 1) {
// we are on the index page
final firstLink = breadcrumbs.querySelector('a');
firstLink.attributes['href'] = pubPackageLink;
firstLink.text = pubPackageText;
} else if (breadcrumbs.children.isNotEmpty) {
// we are inside
final firstLink = breadcrumbs.querySelector('a');
firstLink.text = 'documentation';

final lead = new Element.tag('li');
final leadLink = new Element.tag('a');
leadLink.attributes['href'] = pubPackageLink;
leadLink.text = pubPackageText;
lead.append(leadLink);

breadcrumbs.insertBefore(lead, breadcrumbs.firstChild);
breadcrumbs.insertBefore(new Text('\n '), breadcrumbs.firstChild);
}
}
}
4 changes: 4 additions & 0 deletions app/lib/dartdoc/dartdoc_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import '../shared/utils.dart' show redirectDartdocPages;
import '../shared/versions.dart';

import 'backend.dart';
import 'customization.dart';
import 'models.dart';

final Logger _logger = new Logger('pub.dartdoc.runner');
Expand Down Expand Up @@ -66,6 +67,9 @@ class DartdocRunner implements TaskRunner {
final dartdocEnv = {'PUB_CACHE': pubCacheDir};
final entry = await _generateDocs(task, pkgPath, outputDir, dartdocEnv);

await new DartdocCustomizer(task.package, task.version)
.customizeDir(outputDir);

if (entry.hasContent) {
await dartdocBackend.uploadDir(entry, outputDir);
}
Expand Down
49 changes: 49 additions & 0 deletions app/test/dartdoc/customization_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io';

import 'package:html/parser.dart';
import 'package:test/test.dart';

import 'package:pub_dartlang_org/dartdoc/customization.dart';

const String goldenDir = 'test/dartdoc/golden';

final _regenerateGoldens = false;

void main() {
void expectGoldenFile(String content, String fileName) {
// Making sure it is valid HTML
final htmlParser = new HtmlParser(content, strict: true);
htmlParser.parse();

if (_regenerateGoldens) {
new File('$goldenDir/$fileName').writeAsStringSync(content);
fail('Set `_regenerateGoldens` to `false` to run tests.');
}
final golden = new File('$goldenDir/$fileName').readAsStringSync();
expect(content.split('\n'), golden.split('\n'));
}

group('pana 0.10.2', () {
final customization = new DartdocCustomizer('pana', '0.10.2');

void expectMatch(String name) {
test(name, () {
final inputName = 'pana_0.10.2_$name.html';
final outputName = 'pana_0.10.2_$name.out.html';
final html = new File('$goldenDir/$inputName').readAsStringSync();
final result = customization.customizeHtml(html) ?? html;
expectGoldenFile(result, outputName);
});
}

expectMatch('index');
expectMatch('license_file_class');
expectMatch('license_file_constructor');
expectMatch('license_file_name_field');
expectMatch('pretty_json');
});
}
105 changes: 105 additions & 0 deletions app/test/dartdoc/golden/pana_0.10.2_index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="generator" content="made with love by dartdoc 0.16.0">
<meta name="description" content="pana API docs, for the Dart programming language.">
<title>pana - Dart API docs</title>
<link rel="canonical" href="https://www.dartdocs.org/documentation/pana/0.10.2/index.html">

<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500,400i,400,300|Source+Sans+Pro:400,300,700" rel="stylesheet">
<link rel="stylesheet" href="static-assets/github.css">
<link rel="stylesheet" href="static-assets/styles.css">
<link rel="icon" href="static-assets/favicon.png">

</head>

<body>

<div id="overlay-under-drawer"></div>

<header id="title">
<ol class="breadcrumbs gt-separated dark hidden-xs">
<li><a href="https://github.com/dart-lang/pana">pana package</a></li>
</ol>
<div class="self-name">pana</div>
<form class="search navbar-right" role="search">
<input type="text" id="search-box" autocomplete="off" disabled class="form-control typeahead" placeholder="Loading search...">
</form>
</header>

<main>

<div class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left">
<h5>pana package</h5>


<ol>
<li class="section-title"><a href="index.html#libraries">Libraries</a></li>
<li><a href="pana/pana-library.html">pana</a></li>
</ol>
</div>

<div class="col-xs-12 col-sm-9 col-md-8 main-content">
<section class="desc markdown">
<p><a href="https://travis-ci.org/dart-lang/pana"><img alt="Build Status" src="https://travis-ci.org/dart-lang/pana.svg?branch=master"></a></p>
<p>A library for analyzing Dart packages.</p><ul><li>Validates the code using <a href="https://www.dartlang.org/tools/analyzer">Dart Analyzer</a>.</li><li>Checks code formatting.</li><li>Checks for outdated dependencies.</li><li>Infers supported platforms: Flutter, web, and/or server.</li></ul>
<p>Used by the <a href="https://pub.dartlang.org/">Dart Package site</a>.</p>
<h2>Use as an executable</h2>
<h3>Installation</h3>
<pre class="language-console"><code class="language-console">&gt; pub global activate pana
</code></pre>
<h3>Usage</h3>
<p>You can specify either a package (+ version) or a local directory to analyze:</p>
<pre class="language-dart"><code>Usage: pana [&lt;options&gt;] &lt;package&gt; [&lt;version&gt;]
pana [&lt;options&gt;] --source path &lt;directory&gt;

Options:
-j, --json Output log items as JSON.
-s, --source The source used to find the package.
[hosted (default), path]

--hosted-url The server that hosts &lt;package&gt;.
(defaults to "https://pub.dartlang.org")

--[no-]warning Shows the warning message before potentially destructive operation.
(defaults to on)
</code></pre>
</section>


<section class="summary" id="libraries">
<h2>Libraries</h2>
<dl>
<dt id="pana">
<span class="name"><a href="pana/pana-library.html">pana</a></span>
</dt>
<dd>

</dd>
</dl>
</section>

</div> <!-- /.main-content -->

</main>

<footer>
<span class="no-break">
pana 0.10.2
</span>

</footer>

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="static-assets/typeahead.bundle.min.js"></script>
<script src="static-assets/highlight.pack.js"></script>
<script src="static-assets/URI.js"></script>
<script src="static-assets/script.js"></script>


</body>

</html>
105 changes: 105 additions & 0 deletions app/test/dartdoc/golden/pana_0.10.2_index.out.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="generator" content="made with love by dartdoc 0.16.0">
<meta name="description" content="pana API docs, for the Dart programming language.">
<title>pana - Dart API docs</title>
<link rel="canonical" href="https://www.dartdocs.org/documentation/pana/0.10.2/index.html">

<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500,400i,400,300|Source+Sans+Pro:400,300,700" rel="stylesheet">
<link rel="stylesheet" href="static-assets/github.css">
<link rel="stylesheet" href="static-assets/styles.css">
<link rel="icon" href="static-assets/favicon.png">

</head>

<body>

<div id="overlay-under-drawer"></div>

<header id="title">
<a href="https://pub.dartlang.org/"><img src="https://pub.dartlang.org/static/img/dart-logo.svg" style="height: 30px; margin-right: 1em;"></a>
<ol class="breadcrumbs gt-separated dark hidden-xs">
<li><a href="https://pub.dartlang.org/packages/pana/versions/0.10.2">pana package</a></li>
</ol>
<div class="self-name">pana</div>
<form class="search navbar-right" role="search">
<input type="text" id="search-box" autocomplete="off" disabled="" class="form-control typeahead" placeholder="Loading search...">
</form>
</header>

<main>

<div class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left">
<h5>pana package</h5>


<ol>
<li class="section-title"><a href="index.html#libraries">Libraries</a></li>
<li><a href="pana/pana-library.html">pana</a></li>
</ol>
</div>

<div class="col-xs-12 col-sm-9 col-md-8 main-content">
<section class="desc markdown">
<p><a href="https://travis-ci.org/dart-lang/pana"><img alt="Build Status" src="https://travis-ci.org/dart-lang/pana.svg?branch=master"></a></p>
<p>A library for analyzing Dart packages.</p><ul><li>Validates the code using <a href="https://www.dartlang.org/tools/analyzer">Dart Analyzer</a>.</li><li>Checks code formatting.</li><li>Checks for outdated dependencies.</li><li>Infers supported platforms: Flutter, web, and/or server.</li></ul>
<p>Used by the <a href="https://pub.dartlang.org/">Dart Package site</a>.</p>
<h2>Use as an executable</h2>
<h3>Installation</h3>
<pre class="language-console"><code class="language-console">&gt; pub global activate pana
</code></pre>
<h3>Usage</h3>
<p>You can specify either a package (+ version) or a local directory to analyze:</p>
<pre class="language-dart"><code>Usage: pana [&lt;options&gt;] &lt;package&gt; [&lt;version&gt;]
pana [&lt;options&gt;] --source path &lt;directory&gt;

Options:
-j, --json Output log items as JSON.
-s, --source The source used to find the package.
[hosted (default), path]

--hosted-url The server that hosts &lt;package&gt;.
(defaults to "https://pub.dartlang.org")

--[no-]warning Shows the warning message before potentially destructive operation.
(defaults to on)
</code></pre>
</section>


<section class="summary" id="libraries">
<h2>Libraries</h2>
<dl>
<dt id="pana">
<span class="name"><a href="pana/pana-library.html">pana</a></span>
</dt>
<dd>

</dd>
</dl>
</section>

</div> <!-- /.main-content -->

</main>

<footer>
<span class="no-break">
pana 0.10.2
</span>

</footer>

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="static-assets/typeahead.bundle.min.js"></script>
<script src="static-assets/highlight.pack.js"></script>
<script src="static-assets/URI.js"></script>
<script src="static-assets/script.js"></script>





</body></html>
Loading