generate keyword for searches; improved layout of doc

This commit is contained in:
Misko Hevery 2010-11-15 12:15:27 -08:00
parent a1652057a5
commit b467a50bc7
7 changed files with 225 additions and 190 deletions

View file

@ -9,6 +9,8 @@ var fs = require('fs'),
var documentation = {
pages:[]
};
var keywordPages = [];
var SRC_DIR = "docs/";
var OUTPUT_DIR = "build/docs/";
@ -22,7 +24,11 @@ var work = callback.chain(function () {
findNgDoc(file, work.waitMany(function(doc) {
parseNgDoc(doc);
if (doc.ngdoc) {
delete doc.raw.text;
keywordPages.push({
name:doc.name,
keywords:keywords(doc.raw.text)
}
);
documentation.pages.push(doc);
console.log('Found:', doc.ngdoc + ':' + doc.shortName);
mergeTemplate(
@ -35,11 +41,12 @@ var work = callback.chain(function () {
}).onError(function(err){
console.log('ERROR:', err.stack || err);
}).onDone(function(){
documentation.pages.sort(function(a,b){ return a.name == b.name ? 0:(a.name < b.name ? -1 : 1);});
mergeTemplate('docs-data.js', 'docs-data.js', {JSON:JSON.stringify(documentation)}, callback.chain());
keywordPages.sort(function(a,b){ return a.name == b.name ? 0:(a.name < b.name ? -1 : 1);});
mergeTemplate('docs-data.js', 'docs-data.js', {JSON:JSON.stringify(keywordPages)}, callback.chain());
mergeTemplate('docs-scenario.js', 'docs-scenario.js', documentation, callback.chain());
copy('docs-scenario.html', callback.chain());
copy('index.html', callback.chain());
copy('docs.css', callback.chain());
mergeTemplate('docs.js', 'docs.js', documentation, callback.chain());
mergeTemplate('doc_widgets.css', 'doc_widgets.css', documentation, callback.chain());
mergeTemplate('doc_widgets.js', 'doc_widgets.js', documentation, callback.chain());
@ -48,6 +55,24 @@ var work = callback.chain(function () {
if (!this.testmode) work();
////////////////////
function keywords(text){
var keywords = {};
var words = [];
var tokens = text.toLowerCase().split(/[,\.\`\'\"\s]+/mg);
tokens.forEach(function(key){
var match = key.match(/^(([a-z]|ng\:)[\w\_\-]{2,})/);
if (match){
key = match[1];
if (!keywords[key]) {
keywords[key] = true;
words.push(key);
}
}
});
words.sort();
return words.join(' ');
}
function noop(){}
function mkdirPath(path, callback) {
var parts = path.split(/\//);

View file

@ -1 +1 @@
NG_DOC={{{JSON}}};
NG_PAGES={{{JSON}}};

127
docs/docs.css Normal file
View file

@ -0,0 +1,127 @@
body {
font-family: Arial, sans-serif;
font-size: 14px;
margin: 0;
padding: 0;
}
#page {
display: table-row;
}
#sidebar,
#section {
display: table-cell;
}
a {
color: blue;
}
.nav-section {
margin-left: 1em;
margin-top: 0.5em;
}
.section-title {
float: right;
}
#header {
background-color: #F2C200;
border-bottom: 1px solid #957800;
}
#header h1 {
font-weight: normal;
font-size: 30px;
line-height: 30px;
margin: 0;
padding: 10px 10px;
height: 30px;
}
#header .angular {
font-family: Courier New, monospace;
font-weight: bold;
}
#header h1 a {
color: black;
text-decoration: none;
}
#header h1 a:hover {
text-decoration: underline;
}
#section {
padding: 1em;
}
#section h1 {
font-family: monospace;
margin-top: 0;
padding-bottom: 5px;
border-bottom: 1px solid #CCC;
}
#sidebar {
padding: 10px;
background-color: #EEE;
border-right: 1px solid #DDD;
}
#sidebar a {
text-decoration: none;
}
#sidebar a:hover {
text-decoration: underline;
}
#sidebar input {
width: 175px;
margin-bottom: 1em;
}
#sidebar ul {
list-style-type: none;
/*TODO(esprehn): Can we just reset globally and not break examples?*/
margin: 0;
padding: 0;
}
#sidebar ul li {
}
#sidebar ul li a {
display: block;
padding: 2px 2px 2px 4px;
}
#sidebar ul li.selected a {
background-color: #DDD;
border-radius: 5px;
-moz-border-radius: 5px;
border: 1px solid #CCC;
padding: 1px 1px 1px 3px;
}
#sidebar ul li.level-0 {
margin-left: 0em;
font-weight: bold;
font-size: 1.2em;
}
#sidebar ul li.level-1 {
margin-left: 1em;
margin-top: 5px;
font-size: 1.1em;
font-weight: bold;
}
#sidebar ul li.level-2 {
margin-left: 2em;
font-family: monospace;
}

View file

@ -1,7 +1,34 @@
function DocController($resource, $location){
this.docs = $resource('documentation.json').get();
this.getPartialDoc = function(){
return encodeURIComponent($location.hashPath) + '.html';
SyntaxHighlighter['defaults'].toolbar = false;
DocsController.$inject = ['$location', '$browser'];
function DocsController($location, $browser) {
this.pages = NG_PAGES;
window.$root = this.$root;
this.getUrl = function(page){
return '#!' + encodeURIComponent(page.name);
};
this.getCurrentPartial = function(){
return './' + this.getTitle() + '.html';
};
this.getTitle = function(){
var hashPath = $location.hashPath || '!angular';
if (hashPath.match(/^!angular/)) {
this.partialTitle = hashPath.substring(1);
}
return this.partialTitle;
};
this.getClass = function(page) {
var depth = page.name.split(/\./).length - 1;
return 'level-' + depth +
(page.name == this.getTitle() ? ' selected' : '');
};
}
DocController.$inject=['$resource', '$location'];
angular.filter('short', function(name){
return (name||'').split(/\./).pop();
});

View file

@ -1,179 +1,24 @@
<!DOCTYPE HTML>
<html xmlns:ng="http://angularjs.org/" xmlns:doc="http://docs.angularjs.org/" ng:controller="DocsController">
<head>
<title>&lt;Angular/&gt; Docs</title>
<title>&lt;angular/&gt;: {{getTitle()}}</title>
<meta name="fragment" content="!">
<link rel="stylesheet" href="wiki_widgets.css" type="text/css" media="screen">
<link rel="stylesheet" href="doc_widgets.css" type="text/css" media="screen" />
<link rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" type="text/css" media="screen" />
<link rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" type="text/css" media="screen" />
<link rel="stylesheet" href="doc_widgets.css" type="text/css" />
<link rel="stylesheet" href="docs.css" type="text/css"/>
<link rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" type="text/css"/>
<link rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" type="text/css"/>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script type="text/javascript" src="../angular.min.js" ng:autobind></script>
<script type="text/javascript" src="doc_widgets.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js"></script>
<script type="text/javascript" src="../angular.min.js" ng:autobind></script>
<script type="text/javascript" src="docs.js"></script>
<script type="text/javascript" src="doc_widgets.js"></script>
<script type="text/javascript" src="docs-data.js"></script>
<script type="text/javascript">
SyntaxHighlighter['defaults'].toolbar = false;
DocsController.$inject = ['$location', '$browser']
function DocsController($location, $browser) {
this.docs = NG_DOC;
window.$root = this.$root;
this.getUrl = function(page){
return '#!' + encodeURIComponent(page.name);
};
this.getCurrentPartial = function(){
return './' + this.getTitle() + '.html';
}
this.getTitle = function(){
var hashPath = $location.hashPath || '!angular';
if (hashPath.match(/^!angular/)) {
this.partialTitle = hashPath.substring(1);
}
return this.partialTitle;
}
this.getClass = function(page) {
return 'level-' + page.depth +
(page.name == this.getTitle() ? ' selected' : '');
};
}
</script>
<style type="text/css" media="screen">
body {
font-family: Arial, sans-serif;
font-size: 14px;
margin: 0;
padding: 0;
}
a {
color: blue;
}
.nav-section {
margin-left: 1em;
margin-top: 0.5em;
}
.section-title {
float: right;
}
#header {
background-color: #F2C200;
margin-bottom: 1em;
}
#header h1 {
font-weight: normal;
font-size: 30px;
line-height: 30px;
margin: 0;
padding: 10px 10px;
height: 30px;
}
#header .angular {
font-family: Courier New, monospace;
font-weight: bold;
}
#header h1 a {
color: black;
text-decoration: none;
}
#header h1 a:hover {
text-decoration: underline;
}
#section {
position: absolute;
z-index: -1;
width: 100%;
}
#section ng\:include {
margin: 0 1em 1em 15em;
display: block;
}
#section h1 {
font-family: monospace;
margin-top: 0;
padding-bottom: 5px;
border-bottom: 1px solid #CCC;
}
#sidebar {
width: 180px;
float: left;
padding-left: 1em;
}
#sidebar a {
text-decoration: none;
}
#sidebar a:hover {
text-decoration: underline;
}
#sidebar input {
width: 175px;
margin-bottom: 1em;
}
#sidebar ul {
list-style-type: none;
/*TODO(esprehn): Can we just reset globally and not break examples?*/
margin: 0;
padding: 0;
}
#sidebar ul li {
}
#sidebar ul li a {
display: block;
padding: 2px 2px 2px 4px;
}
#sidebar ul li.selected a {
background-color: #DDD;
border-radius: 5px;
-moz-border-radius: 5px;
border: 1px solid #CCC;
padding: 1px 1px 1px 3px;
}
#sidebar ul li.level-0 {
margin-left: 0em;
font-weight: bold;
font-size: 1.2em;
}
#sidebar ul li.level-1 {
margin-left: 1em;
margin-top: 5px;
font-size: 1.1em;
font-weight: bold;
}
#sidebar ul li.level-2 {
margin-left: 2em;
font-family: monospace;
}
</style>
<title>&lt;angular/&gt;: {{getTitle()}}</title>
</head>
<body>
<div id="header">
@ -182,18 +27,20 @@
<a href="index.html"><span class="angular">&lt;angular/&gt;</span> Docs</a>
</h1>
</div>
<div id="sidebar" class="nav">
<div>
<input type="text" name="filterText" placeholder="search documentaiton"/>
<ul>
<li ng:repeat="page in docs.pages.$filter(filterText)" ng:class="getClass(page)">
<a href="{{getUrl(page)}}" ng:click="">{{page.shortName}}</a>
</li>
</ul>
</div>
</div>
<div id="section">
<ng:include src="getCurrentPartial()"></ng:include>
<div id="page">
<div id="sidebar" class="nav">
<div class="doc-list">
<input type="text" name="filterText" placeholder="search documentaiton"/>
<ul>
<li ng:repeat="page in pages.$filter(filterText)" ng:class="getClass(page)">
<a href="{{getUrl(page)}}" ng:click="">{{page.name | short}}</a>
</li>
</ul>
</div>
</div>
<div id="section">
<ng:include src="getCurrentPartial()"></ng:include>
</div>
</div>
</body>
</html>

View file

@ -69,6 +69,14 @@ describe('collect', function(){
});
});
describe('keywords', function(){
var keywords = collect.keywords;
it('should collect keywords', function(){
expect(keywords('\nHello: World! @ignore.')).toEqual('hello world');
expect(keywords('The `ng:class-odd` and ')).toEqual('and ng:class-odd the');
});
});
});
function load(path){

View file

@ -19,8 +19,9 @@ function createInjector(providerScope, providers, cache) {
* string: return an instance for the injection key.
* array of keys: returns an array of instances.
* function: look at $inject property of function to determine instances
* and then call the function with instances and scope. Any
* additional arguments are passed on to function.
* and then call the function with instances and `scope`. Any
* additional arguments (`args`) are appended to the function
* arguments.
* object: initialize eager providers and publish them the ones with publish here.
* none: same as object but use providerScope as place to publish.
*/