1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ // @ts -check
18
+ const Documentation = require ( './documentation' ) ;
19
+ const { visitAll } = require ( '../markdown' ) ;
20
+ /**
21
+ * @param {Documentation.MarkdownNode[] } nodes
22
+ * @param {number } maxColumns
23
+ */
24
+ function renderXmlDoc ( nodes , maxColumns = 80 , prefix = '/// ' ) {
25
+ if ( ! nodes )
26
+ return [ ] ;
27
+
28
+ const renderResult = _innerRenderNodes ( nodes , maxColumns ) ;
29
+
30
+ const doc = [ ] ;
31
+ _wrapInNode ( 'summary' , renderResult . summary , doc ) ;
32
+ _wrapInNode ( 'remarks' , renderResult . remarks , doc ) ;
33
+ return doc . map ( x => `${ prefix } ${ x } ` ) ;
34
+ }
35
+
36
+ function _innerRenderNodes ( nodes , maxColumns = 80 , wrapParagraphs = true ) {
37
+ const summary = [ ] ;
38
+ const remarks = [ ] ;
39
+ const handleListItem = ( lastNode , node ) => {
40
+ if ( node && node . type === 'li' && ( ! lastNode || lastNode . type !== 'li' ) )
41
+ summary . push ( `<list type="${ node . liType } ">` ) ;
42
+ else if ( lastNode && lastNode . type === 'li' && ( ! node || node . type !== 'li' ) )
43
+ summary . push ( '</list>' ) ;
44
+
45
+ } ;
46
+
47
+ let lastNode ;
48
+ visitAll ( nodes , node => {
49
+ // handle special cases first
50
+ if ( _nodeShouldBeIgnored ( node ) )
51
+ return ;
52
+ if ( node . text && node . text . startsWith ( 'extends: ' ) ) {
53
+ remarks . push ( 'Inherits from ' + node . text . replace ( 'extends: ' , '' ) ) ;
54
+ return ;
55
+ }
56
+ handleListItem ( lastNode , node ) ;
57
+ if ( node . type === 'text' ) {
58
+ if ( wrapParagraphs )
59
+ _wrapInNode ( 'para' , _wrapAndEscape ( node , maxColumns ) , summary ) ;
60
+ else
61
+ summary . push ( ..._wrapAndEscape ( node , maxColumns ) ) ;
62
+ } else if ( node . type === 'code' && node . codeLang === 'csharp' ) {
63
+ _wrapInNode ( 'code' , node . lines , summary ) ;
64
+ } else if ( node . type === 'li' ) {
65
+ _wrapInNode ( 'item><description' , _wrapAndEscape ( node , maxColumns ) , summary , '/description></item' ) ;
66
+ } else if ( node . type === 'note' ) {
67
+ _wrapInNode ( 'para' , _wrapAndEscape ( node , maxColumns ) , remarks ) ;
68
+ }
69
+ lastNode = node ;
70
+ } ) ;
71
+ handleListItem ( lastNode , null ) ;
72
+
73
+ return { summary, remarks } ;
74
+ }
75
+
76
+ function _wrapInNode ( tag , nodes , target , closingTag = null ) {
77
+ if ( nodes . length === 0 )
78
+ return ;
79
+
80
+ if ( ! closingTag )
81
+ closingTag = `/${ tag } ` ;
82
+
83
+ if ( nodes . length === 1 ) {
84
+ target . push ( `<${ tag } >${ nodes [ 0 ] } <${ closingTag } >` ) ;
85
+ return ;
86
+ }
87
+
88
+ target . push ( `<${ tag } >` ) ;
89
+ target . push ( ...nodes ) ;
90
+ target . push ( `<${ closingTag } >` ) ;
91
+ }
92
+
93
+ /**
94
+ *
95
+ * @param {Documentation.MarkdownNode } node
96
+ */
97
+ function _wrapAndEscape ( node , maxColumns = 0 ) {
98
+ const lines = [ ] ;
99
+ const pushLine = text => {
100
+ if ( text === '' )
101
+ return ;
102
+ text = text . trim ( ) ;
103
+ lines . push ( text ) ;
104
+ } ;
105
+
106
+ const text = node . text . replace ( / [ ^ \[ ] ` ( [ ^ \] ] * [ ^ \[ ] ) ` [ ^ \] ] / g, ( m , g1 ) => ` <c>${ g1 } </c> ` ) ;
107
+ const words = text . split ( ' ' ) ;
108
+ let line = '' ;
109
+ for ( let i = 0 ; i < words . length ; i ++ ) {
110
+ line = line + ' ' + words [ i ] ;
111
+ if ( line . length >= maxColumns ) {
112
+ pushLine ( line ) ;
113
+ line = '' ;
114
+ }
115
+ }
116
+
117
+ pushLine ( line ) ;
118
+ return lines ;
119
+ }
120
+
121
+ /**
122
+ *
123
+ * @param {Documentation.MarkdownNode } node
124
+ */
125
+ function _nodeShouldBeIgnored ( node ) {
126
+ if ( ! node
127
+ || ( node . text === 'extends: [EventEmitter]' ) )
128
+ return true ;
129
+
130
+ return false ;
131
+ }
132
+
133
+ /**
134
+ * @param {Documentation.MarkdownNode[] } nodes
135
+ */
136
+ function renderTextOnly ( nodes , maxColumns = 80 ) {
137
+ const result = _innerRenderNodes ( nodes , maxColumns , false ) ;
138
+ return result . summary ;
139
+ }
140
+
141
+ module . exports = { renderXmlDoc, renderTextOnly }
0 commit comments