1
1
'use strict' ;
2
2
3
- var getGlobalExternalLink = require ( 'globals-docs' ) . getDoc ,
3
+ var getDoc = require ( 'globals-docs' ) . getDoc ,
4
+ formatType = require ( './format_type' ) ,
4
5
mdast = require ( 'mdast' ) ,
5
6
html = require ( 'mdast-html' ) ,
6
7
inlineLex = require ( 'jsdoc-inline-lex' ) ;
7
8
8
- /**
9
- * Format a description and target as a Markdown link.
10
- *
11
- * @param {string } description the text seen as the link
12
- * @param {string } href where the link goes
13
- * @return {string } markdown formatted link
14
- */
15
- function markdownLink ( description , href ) {
16
- return '[`' + description + '`](' + href + ')' ;
17
- }
18
-
19
9
/**
20
10
* Format link & tutorial tags with simple code inline tags.
21
11
*
12
+ * @param {Array<string> } paths potential linkable namepaths
22
13
* @param {string } text input - typically a description
23
14
* @returns {string } markdown-friendly output
24
15
* @private
25
16
* @example
26
17
* formatInlineTags('{@link Foo}'); // "[Foo](#foo)"
27
18
*/
28
- function formatInlineTags ( text ) {
19
+ function formatInlineTags ( paths , text ) {
29
20
var output = '' ;
30
21
var tokens = inlineLex ( text ) ;
31
22
32
23
for ( var i = 0 ; i < tokens . length ; i ++ ) {
33
24
if ( tokens [ i ] . type === 'text' ) {
34
25
output += tokens [ i ] . capture [ 0 ] ;
35
26
} else if ( tokens [ i ] . type === 'link' ) {
36
- var parts = tokens [ i ] . capture [ 1 ] . split ( / \s | \| / ) ;
37
- if ( parts . length === 1 ) {
38
- output += markdownLink ( tokens [ i ] . capture [ 1 ] , tokens [ i ] . capture [ 1 ] ) ;
27
+ var described = tokens [ i ] . capture [ 1 ] . match ( / ( [ ^ \s | \| ] * ) ( \s | \| ) ( .* ) / ) ;
28
+ if ( described ) {
29
+ // 1 is the match, 3 is description
30
+ output += autolink ( paths , described [ 1 ] , described [ 3 ] ) ;
39
31
} else {
40
- output += markdownLink ( parts . slice ( 1 ) . join ( ' ' ) , parts [ 0 ] ) ;
32
+ output += autolink ( paths , tokens [ i ] . capture [ 1 ] ) ;
41
33
}
42
34
} else if ( tokens [ i ] . type === 'prefixLink' ) {
43
- output += markdownLink ( tokens [ i ] . capture [ 1 ] , tokens [ i ] . capture [ 2 ] ) ;
35
+ output += autolink ( paths , tokens [ i ] . capture [ 1 ] , tokens [ i ] . capture [ 2 ] ) ;
44
36
}
45
37
}
46
38
47
39
return output ;
48
40
}
49
41
50
- /**
51
- * Link text to this page or to a central resource.
52
- * @param {Array<string> } paths list of valid namespace paths that are linkable
53
- * @param {string } text inner text of the link
54
- * @returns {string } potentially linked HTML
55
- */
56
- function autolink ( paths , text ) {
57
- if ( paths . indexOf ( text ) !== - 1 ) {
58
- return '<a href="#' + text + '">' + text + '</a>' ;
59
- } else if ( getGlobalExternalLink ( text ) ) {
60
- return '<a href="' + getGlobalExternalLink ( text ) + '">' + text + '</a>' ;
61
- }
62
- return text ;
63
- }
64
-
65
- /**
66
- * Helper used to format JSDoc-style type definitions into HTML.
67
- *
68
- * @name formatType
69
- * @param {Object } type type object in doctrine style
70
- * @param {Array<string> } paths valid namespace paths that can be linked
71
- * @returns {string } string
72
- * @example
73
- * var x = { type: 'NameExpression', name: 'String' };
74
- * // in template
75
- * // {{ type x }}
76
- * // generates String
77
- */
78
- function formatType ( type , paths ) {
79
- if ( ! type ) {
80
- return '' ;
81
- }
82
- function recurse ( element ) {
83
- return formatType ( element , paths ) ;
84
- }
85
- switch ( type . type ) {
86
- case 'NameExpression' :
87
- return '<code>' + autolink ( paths , type . name ) + '</code>' ;
88
- case 'UnionType' :
89
- return type . elements . map ( recurse ) . join ( ' or ' ) ;
90
- case 'AllLiteral' :
91
- return 'Any' ;
92
- case 'RestType' :
93
- return '...' + formatType ( type . expression , paths ) ;
94
- case 'OptionalType' :
95
- case 'NullableType' :
96
- return '<code>[' + formatType ( type . expression , paths ) + ']</code>' ;
97
- case 'TypeApplication' :
98
- return formatType ( type . expression , paths ) + '<' +
99
- type . applications . map ( recurse ) . join ( ', ' ) + '>' ;
100
- case 'UndefinedLiteral' :
101
- return 'undefined' ;
102
- }
103
- }
104
-
105
42
/**
106
43
* Format a parameter name. This is used in formatParameters
107
44
* and just needs to be careful about differentiating optional
@@ -131,6 +68,35 @@ function formatParameters() {
131
68
} ) . join ( ', ' ) + ')' ;
132
69
}
133
70
71
+ /**
72
+ * Link text to this page or to a central resource.
73
+ * @param {Array<string> } paths list of valid namespace paths that are linkable
74
+ * @param {string } text inner text of the link
75
+ * @returns {string? } potentially a url
76
+ */
77
+ function getNamedLink ( paths , text ) {
78
+ if ( paths . indexOf ( text ) !== - 1 ) {
79
+ return '#' + text ;
80
+ } else if ( getDoc ( text ) ) {
81
+ return getDoc ( text ) ;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Link text to this page or to a central resource.
87
+ * @param {Array<string> } paths list of valid namespace paths that are linkable
88
+ * @param {string } text inner text of the link
89
+ * @param {string } description link text override
90
+ * @returns {string } potentially linked HTML
91
+ */
92
+ function autolink ( paths , text , description ) {
93
+ var url = getNamedLink ( paths , text ) ;
94
+ if ( url ) {
95
+ return '<a href="' + url + '">' + ( description || text ) + '</a>' ;
96
+ }
97
+ return text ;
98
+ }
99
+
134
100
/**
135
101
* Given a Handlebars instance, register helpers
136
102
*
@@ -139,6 +105,7 @@ function formatParameters() {
139
105
* @returns {undefined } invokes side effects on Handlebars
140
106
*/
141
107
function htmlHelpers ( Handlebars , paths ) {
108
+
142
109
Handlebars . registerHelper ( 'permalink' , function ( ) {
143
110
return this . path . join ( '.' ) ;
144
111
} ) ;
@@ -147,6 +114,10 @@ function htmlHelpers(Handlebars, paths) {
147
114
148
115
Handlebars . registerHelper ( 'format_params' , formatParameters ) ;
149
116
117
+ var htmlOptions = {
118
+ entities : false
119
+ } ;
120
+
150
121
/**
151
122
* This helper is exposed in templates as `md` and is useful for showing
152
123
* Markdown-formatted text as proper HTML.
@@ -161,11 +132,19 @@ function htmlHelpers(Handlebars, paths) {
161
132
* // generates <h2>foo</h2>
162
133
*/
163
134
Handlebars . registerHelper ( 'md' , function formatMarkdown ( string ) {
164
- return new Handlebars . SafeString ( mdast ( ) . use ( html ) . process ( formatInlineTags ( string ) ) ) ;
135
+ return new Handlebars . SafeString ( mdast ( ) . use ( html , htmlOptions )
136
+ . process ( formatInlineTags ( paths , string ) ) ) ;
165
137
} ) ;
166
138
167
139
Handlebars . registerHelper ( 'format_type' , function ( type ) {
168
- return formatType ( type , paths ) ;
140
+ if ( ! type ) {
141
+ return '' ;
142
+ }
143
+ return new Handlebars . SafeString ( mdast ( ) . use ( html , htmlOptions )
144
+ . stringify ( {
145
+ type : 'root' ,
146
+ children : formatType ( type , paths )
147
+ } ) ) ;
169
148
} ) ;
170
149
}
171
150
0 commit comments