Skip to content
This repository has been archived by the owner on Jan 23, 2022. It is now read-only.

Commit

Permalink
feat(docs): optional view source and improve this doc links #25
Browse files Browse the repository at this point in the history
Based on the great work of LFDM
  • Loading branch information
m7r committed Feb 11, 2015
1 parent 4c3d3c3 commit a42e2f7
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 33 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,26 @@ Optional include Google Analytics in the documentation app.
####discussions
Optional include [discussions](http://disqus.com) in the documentation app.

####sourceLink
[default] true
Display "View source" link.
Possible values are
- `true`: try to read repository from package.json (currently only github is supported)
- `false`: don't display link
- string: template string like `'https://internal.server/repo/blob/{{sha}}/{{file}}#L{{codeline}}'`
available placeholders:
- **file**: path and filename current file
- **filename**: only filename of current file
- **filepath**: directory of current file
- **line**: first line of comment
- **codeline**: first line *after* comment
- **version**: version read from package.json
- **sha**: first 7 characters of current git commit

####editLink
[default] true
Display "Improve this doc" link. Same options as for sourceLink.

####editExample
[default] true
Show Edit Button for examples.
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"license": "MIT",
"readmeFilename": "README.md",
"dependencies": {
"marked": "~0.3.2"
"marked": "~0.3.2",
"shelljs": "~0.3.0"
},
"peerDependencies": {
"grunt": "0.4.x"
Expand Down
50 changes: 23 additions & 27 deletions src/ngdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,16 @@ var BOOLEAN_ATTR = {};
});

//////////////////////////////////////////////////////////
function Doc(text, file, line, options) {
function Doc(text, file, startLine, endLine, options) {
if (typeof text == 'object') {
for ( var key in text) {
this[key] = text[key];
}
} else {
this.text = text;
this.file = file;
this.line = line;
this.line = startLine;
this.codeline = endLine + 1;
}
this.options = options || {};
this.scenarios = this.scenarios || [];
Expand Down Expand Up @@ -470,35 +471,24 @@ Doc.prototype = {
self = this,
minerrMsg;

var gitTagFromFullVersion = function(version) {
var match = version.match(/-(\w{7})/);

if (match) {
// git sha
return match[1];
}

// git tag
return 'v' + version;
};
if (this.options.editLink) {
dom.tag('a', {
href: self.options.editLink(self.file, self.line, self.codeline),
class: 'improve-docs' }, function(dom) {
dom.tag('i', {class:'icon-edit'}, ' ');
dom.text('Improve this doc');
});
}

/*
if (this.section === 'api') {
if (this.options.sourceLink && this.options.isAPI) {
dom.tag('a', {
href: 'http://github.com/angular/angular.js/tree/' +
gitTagFromFullVersion(gruntUtil.getVersion().full) + '/' + self.file + '#L' + self.line,
class: 'view-source btn btn-action' }, function(dom) {
dom.tag('i', {class:'icon-zoom-in'}, ' ');
dom.text(' View source');
href: self.options.sourceLink(self.file, self.line, self.codeline),
class: 'view-source' }, function(dom) {
dom.tag('i', {class:'icon-eye-open'}, ' ');
dom.text('View source');
});
}
dom.tag('a', {
href: 'http://github.com/angular/angular.js/edit/master/' + self.file,
class: 'improve-docs btn btn-primary' }, function(dom) {
dom.tag('i', {class:'icon-edit'}, ' ');
dom.text(' Improve this doc');
});
*/

dom.h(title(this), function() {
notice('deprecated', 'Deprecated API', self.deprecated);
if (self.ngdoc === 'error') {
Expand Down Expand Up @@ -892,6 +882,12 @@ Doc.prototype = {
if (self.methods.length) {
dom.div({class:'member method'}, function(){
dom.h('Methods', self.methods, function(method){
if (self.options.sourceLink) {
dom.tag('a', {
href: self.options.sourceLink(method.file, method.line, method.codeline),
class: 'view-source icon-eye-open'
}, ' ');
}
//filters out .IsProperty parameters from the method signature
var signature = (method.param || []).filter(function(e) { return e.isProperty !== true; }).map(property('name'));
dom.h(method.shortName + '(' + signature.join(', ') + ')', method, function() {
Expand Down
2 changes: 1 addition & 1 deletion src/reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function processJsFile(content, file, section, options) {
text = text.replace(/^\n/, '');
if (text.match(/@ngdoc/)){
//console.log(file, startingLine)
docs.push(new ngdoc.Doc('@section ' + section + '\n' + text, file, startingLine, options).parse());
docs.push(new ngdoc.Doc('@section ' + section + '\n' + text, file, startingLine, lineNumber, options).parse());
}
doc = null;
inDoc = false;
Expand Down
23 changes: 21 additions & 2 deletions src/templates/css/docs.css
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,27 @@ img.AngularJS-small {
/* Content */
/* =============================== */

.improve-docs {
.edit-example {
margin-top: 9px;
}

.improve-docs, .view-source, .edit-example {
float: right;
margin-left: 35px;
position: relative;
}

.improve-docs i, .view-source i, .edit-example i {
position: absolute;
left: -20px;
top: 50%;
margin-top: -.5em;
text-decoration: none !important;
}

.methods .view-source {
margin: -0.5em 0 0 0;
text-decoration: none !important;
}

.hint {
Expand Down Expand Up @@ -218,7 +237,7 @@ ul.methods > li > h3,
ul.properties > li > h3,
ul.events > li > h3 {
margin: -19px -19px 1em -19px;
padding: .25em 19px;
padding: .25em 39px .25em 19px;
background-color: #d3d3d3;
font-family: monospace;
}
Expand Down
57 changes: 55 additions & 2 deletions tasks/grunt-ngdocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ var reader = require('../src/reader.js'),
path = require('path'),
vm = require('vm');

var repohosts = [
{ re: /https?:\/\/github.com\/([^\/]+\/[^\/]+)|git@github.com:(.*)\.git/,
sourceLink: 'https://github.com/{{repo}}/blob/{{sha}}/{{file}}#L{{codeline}}',
editLink: 'https://github.com/{{repo}}/edit/master/{{file}}'
}
];

module.exports = function(grunt) {
var _ = grunt.util._,
templates = path.resolve(__dirname, '../src/templates');
Expand All @@ -26,7 +33,9 @@ module.exports = function(grunt) {
styles: [],
title: pkg.title || pkg.name || '',
html5Mode: true,
editExample: true
editExample: true,
sourceLink: true,
editLink: true
}),
section = this.target === 'all' ? 'api' : this.target,
setup;
Expand Down Expand Up @@ -72,10 +81,13 @@ module.exports = function(grunt) {

grunt.log.writeln('Generating Documentation...');

prepareLinks(pkg, options);

reader.docs = [];
this.files.forEach(function(f) {
options.isAPI = f.api || section == 'api';
setup.sections[section] = f.title || 'API Documentation';
setup.apis[section] = f.api || section == 'api';
setup.apis[section] = options.isAPI;
f.src.filter(exists).forEach(function(filepath) {
var content = grunt.file.read(filepath);
reader.process(content, filepath, section, options);
Expand Down Expand Up @@ -115,6 +127,47 @@ module.exports = function(grunt) {
return pkg || {};
}

function makeLinkFn(tmpl, values) {
if (!tmpl || tmpl === true) { return false; }
if (/\{\{\s*sha\s*\}\}/.test(tmpl)) {
var shell = require('shelljs');
var sha = shell.exec('git rev-parse HEAD', { silent: true });
values.sha = ('' + sha.output).slice(0, 7);
}
tmpl = _.template(tmpl, undefined, {'interpolate': /\{\{(.+?)\}\}/g});
return function(file, line, codeline) {
values.file = file;
values.line = line;
values.codeline = codeline;
values.filepath = path.dirname(file);
values.filename = path.basename(file);
return tmpl(values);
};
}

function prepareLinks(pkg, options) {
var values = {version: pkg.version || 'master'};
var url = (pkg.repository || {}).url;

if (url && options.sourceLink === true || options.sourceEdit === true) {
repohosts.some(function(host) {
var match = url.match(host.re);
if (match) {
values.repo = match[1];
if (host.sourceLink && options.sourceLink === true) {
options.sourceLink = host.sourceLink;
}
if (host.editLink && options.editLink === true) {
options.editLink = host.editLink;
}
}
return match;
});
}
options.sourceLink = makeLinkFn(options.sourceLink, values);
options.editLink = makeLinkFn(options.editLink, values);
}

function prepareSetup(section, options) {
var setup, data, context = {},
file = path.resolve(options.dest, 'js/docs-setup.js');
Expand Down

0 comments on commit a42e2f7

Please sign in to comment.