Skip to content

Commit 56a01b3

Browse files
committed
Isolate markdown renderer and add beginning of custom linking
1 parent e6e7f17 commit 56a01b3

File tree

9 files changed

+135
-96
lines changed

9 files changed

+135
-96
lines changed

_src/app/docs/src/collectMemberGroups.js

+2-5
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,8 @@ function collectMemberGroups(interfaceDef, options) {
2929
function collectFromDef(def, name) {
3030

3131
def.groups && def.groups.forEach(g => {
32-
Seq(g.properties).forEach((propDef, propName) => {
33-
collectMember(g.title || '', propName, propDef);
34-
});
35-
Seq(g.methods).forEach((methodDef, memberName) => {
36-
collectMember(g.title || '', memberName, methodDef);
32+
Seq(g.members).forEach((memberDef, memberName) => {
33+
collectMember(g.title || '', memberName, memberDef);
3734
});
3835
});
3936

_src/resources/immutable.d.json

+1-1
Large diffs are not rendered by default.

_src/src/DocVisitor.js

+15-63
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
var TypeScript = require('./typescript-services');
22
var TypeKind = require('./TypeKind');
3-
var prism = require('./prism');
43
var { Seq } = require('immutable');
5-
var marked = require('marked');
64

75

86
class DocVisitor extends TypeScript.SyntaxWalker {
@@ -90,14 +88,14 @@ class DocVisitor extends TypeScript.SyntaxWalker {
9088
if (!shouldIgnore(comment) && !this.isAliased(name)) {
9189
this.addAliases(comment, name);
9290

93-
var callSignature = this.parseCallSignature(node.callSignature);
94-
callSignature.line = this.getLineNum(node);
95-
pushIn(this.data, [name, 'call', 'signatures'], callSignature);
96-
9791
var comment = this.getDoc(node);
9892
if (comment) {
9993
setIn(this.data, [name, 'call', 'doc'], comment);
10094
}
95+
96+
var callSignature = this.parseCallSignature(node.callSignature);
97+
callSignature.line = this.getLineNum(node);
98+
pushIn(this.data, [name, 'call', 'signatures'], callSignature);
10199
}
102100
super.visitFunctionDeclaration(node);
103101
}
@@ -191,13 +189,13 @@ class DocVisitor extends TypeScript.SyntaxWalker {
191189
// name: name // redundant
192190
};
193191

194-
setIn(last(this.data.groups), ['properties', '#'+name], propertyObj);
195-
196192
var comment = this.getDoc(node);
197193
if (comment) {
198-
setIn(last(this.data.groups), ['properties', '#'+name, 'doc'], comment);
194+
setIn(last(this.data.groups), ['members', '#'+name, 'doc'], comment);
199195
}
200196

197+
setIn(last(this.data.groups), ['members', '#'+name], propertyObj);
198+
201199
if (node.questionToken) {
202200
throw new Error('NYI: questionToken');
203201
}
@@ -217,15 +215,15 @@ class DocVisitor extends TypeScript.SyntaxWalker {
217215

218216
this.ensureGroup(node);
219217

220-
var callSignature = this.parseCallSignature(node.callSignature);
221-
callSignature.line = this.getLineNum(node);
222-
pushIn(last(this.data.groups), ['methods', '#'+name, 'signatures'], callSignature);
223-
224218
var comment = this.getDoc(node);
225219
if (comment) {
226-
setIn(last(this.data.groups), ['methods', '#'+name, 'doc'], comment);
220+
setIn(last(this.data.groups), ['members', '#'+name, 'doc'], comment);
227221
}
228222

223+
var callSignature = this.parseCallSignature(node.callSignature);
224+
callSignature.line = this.getLineNum(node);
225+
pushIn(last(this.data.groups), ['members', '#'+name, 'signatures'], callSignature);
226+
229227
if (node.questionToken) {
230228
throw new Error('NYI: questionToken');
231229
}
@@ -404,69 +402,23 @@ function parseComment(node) {
404402
var notes = lines
405403
.map(l => l.match(COMMENT_NOTE_RX))
406404
.filter(n => n !== null && !NOTE_BLACKLIST[n[1]])
407-
.map(n => {
408-
var name = n[1];
409-
var body = n[2];
410-
if (name !== 'alias') {
411-
body = parseMarkdown(body);
412-
}
413-
return { name, body };
414-
});
405+
.map(n => ({ name: n[1], body: n[2] }));
415406
var paragraphs =
416407
lines.filter(l => !COMMENT_NOTE_RX.test(l)).join('\n').split('\n\n');
417-
var synopsis = parseMarkdown(paragraphs.shift());
408+
var synopsis = paragraphs.shift();
418409
var description = paragraphs.join('\n\n');
419410

420411
var comment = { synopsis };
421412
if (notes.length) {
422413
comment.notes = notes;
423414
}
424415
if (description) {
425-
comment.description = parseMarkdown(description);
416+
comment.description = description;
426417
}
427418

428419
return comment;
429420
}
430421

431-
// functions come before keywords
432-
prism.languages.insertBefore('javascript', 'keyword', {
433-
'block-keyword': /\b(if|else|while|for|function)\b/g,
434-
'function': prism.languages.function
435-
});
436-
437-
marked.setOptions({
438-
highlight: function (code) {
439-
return prism.highlight(code, prism.languages.javascript);
440-
}
441-
});
442-
443-
var renderer = new marked.Renderer();
444-
445-
renderer.code = function(code, lang, escaped) {
446-
if (this.options.highlight) {
447-
var out = this.options.highlight(code, lang);
448-
if (out != null && out !== code) {
449-
escaped = true;
450-
code = out;
451-
}
452-
}
453-
return '<code class="codeBlock">' +
454-
(escaped ? code : escapeCode(code, true)) +
455-
'</code>';
456-
};
457-
458-
function escapeCode(code) {
459-
return code
460-
.replace(/&/g, '&amp;')
461-
.replace(/</g, '&lt;')
462-
.replace(/>/g, '&gt;')
463-
.replace(/"/g, '&quot;')
464-
.replace(/'/g, '&#39;');
465-
}
466-
467-
function parseMarkdown(content) {
468-
return content ? marked(content, { renderer }) : content;
469-
}
470422

471423
function shouldIgnore(comment) {
472424
return !!(comment && Seq(comment.notes).find(

_src/src/genTypeDefData.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var TypeScript = require('./typescript-services');
22
require('node-jsx').install({harmony: true});
33
var DocVisitor = require('./DocVisitor');
4+
var markdownDocs = require('./markdownDocs');
45

56

67
function genTypeDefData(typeDefPath, typeDefSource) {
@@ -10,6 +11,7 @@ function genTypeDefData(typeDefPath, typeDefSource) {
1011
var visitor = new DocVisitor(typeDefText);
1112
TypeScript.visitNodeOrToken(visitor, typeDefAST.sourceUnit());
1213
var typeDefData = visitor.pop();
14+
markdownDocs(typeDefData);
1315
return typeDefData;
1416
}
1517

_src/src/markdownDocs.js

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
var { Seq } = require('immutable');
2+
var marked = require('marked');
3+
var prism = require('./prism');
4+
5+
6+
function markdownDocs(typeDefs, namePath) {
7+
namePath = namePath || [];
8+
Seq(typeDefs).forEach((typeDef, typeName) => {
9+
var typeNamePath = namePath.concat(typeName);
10+
console.log(typeNamePath);
11+
markdownDoc(typeDef.doc, { typeNamePath });
12+
typeDef.call && markdownDoc(typeDef.call.doc);
13+
if (typeDef.interface) {
14+
markdownDoc(typeDef.interface.doc, { typeNamePath });
15+
Seq(typeDef.interface.groups).forEach(group =>
16+
Seq(group.members).forEach((member, memberName) =>
17+
markdownDoc(member.doc, { typeNamePath })
18+
)
19+
);
20+
}
21+
typeDef.module && markdownDocs(typeDef.module, typeNamePath);
22+
});
23+
}
24+
25+
function markdownDoc(doc, context) {
26+
if (!doc) {
27+
return;
28+
}
29+
doc.synopsis && (doc.synopsis = markdown(doc.synopsis, context));
30+
doc.description && (doc.description = markdown(doc.description, context));
31+
doc.notes && doc.notes.forEach(note => {
32+
if (note.name !== 'alias') {
33+
note.body = markdown(note.body, context);
34+
}
35+
});
36+
}
37+
38+
// functions come before keywords
39+
prism.languages.insertBefore('javascript', 'keyword', {
40+
'block-keyword': /\b(if|else|while|for|function)\b/g,
41+
'function': prism.languages.function
42+
});
43+
44+
marked.setOptions({
45+
xhtml: true,
46+
highlight: code => prism.highlight(code, prism.languages.javascript)
47+
});
48+
49+
var renderer = new marked.Renderer();
50+
51+
renderer.code = function(code, lang, escaped) {
52+
if (this.options.highlight) {
53+
var out = this.options.highlight(code, lang);
54+
if (out != null && out !== code) {
55+
escaped = true;
56+
code = out;
57+
}
58+
}
59+
return '<code class="codeBlock">' +
60+
(escaped ? code : escapeCode(code, true)) +
61+
'</code>';
62+
};
63+
64+
var METHOD_RX = /^(\w+)[#.](\w+)$/;
65+
var MDN_BASE_URL = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/';
66+
67+
renderer.codespan = function(text) {
68+
var method = METHOD_RX.exec(text);
69+
if (method) {
70+
if (method[1] === 'Array' || method[1] === 'Object') {
71+
text = '<a href="'+MDN_BASE_URL+method[1]+'/'+method[2]+'">'+text+'</a>';
72+
}
73+
}
74+
return '<code>' + text + '</code>';
75+
};
76+
77+
function escapeCode(code) {
78+
return code
79+
.replace(/&/g, '&amp;')
80+
.replace(/</g, '&lt;')
81+
.replace(/>/g, '&gt;')
82+
.replace(/"/g, '&quot;')
83+
.replace(/'/g, '&#39;');
84+
}
85+
86+
function markdown(content, context) {
87+
// `\w+(\.|#)\w+`
88+
return content ? marked(content, { renderer, context }) : content;
89+
}
90+
91+
module.exports = markdownDocs;

docs/bundle.js

+3-6
Large diffs are not rendered by default.

docs/index.html

+19-19
Large diffs are not rendered by default.

docs/maps/bundle.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.html

+1-1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)