# src/view/MainComment.ts

`

1<comment>/**</comment>

2<comment> * Processing of comments.</comment>

3<comment> */</comment>

4

5<comment>/** */</comment>

6import { m, Vnode } from <quote>'hslayout'</quote>;

7import { markDown } from <quote>'../markdown'</quote>;

8import { example } from <quote>'./MainExample'</quote>;

9

10<comment>/**</comment>

11<comment> * Main comment processing. The result appears directly below the title in the main panel.</comment>

12<comment> * Function parameters are not reported in short form here since it is assumed they will be listed </comment>

13<comment> * individually below the main comment</comment>

14<comment> * @param mdl the module to scan for comments</comment>

15<comment> * @return a vnode representing the comment entries</comment>

16<comment> */</comment>

17export function commentLong(mdl:any):Vnode {

18 let content:any[] = [];

19 if (mdl.comment) {

20 content.push(textOrShortTextOrDescription(mdl.comment, false));

21 content.push(returns(mdl.comment, false));

22 content.push(commentRemainder(mdl.comment));

23 }

24 return m(<quote>'.hs-item-comment'</quote>, content);

25}

26

27<comment>/**</comment>

28<comment> * Shortended comment processing. This form is used to report on subitems below the main panel item.</comment>

29<comment> * If `short` is true, only the first paragraph of the main comment will be returned. Otherwise, </comment>

30<comment> * this function creates a full comment including an inline list of parameters and the return value</comment>

31<comment> * @param mdl the module to scan for comments</comment>

32<comment> * @param short if true, only the first paragraph of the main comment is processed.</comment>

33<comment> * @return a vnode representing the comment entries</comment>

34<comment> */</comment>

35export function comment(mdl:any, short=false):Vnode {

36 let content:any[] = [];

37 if (mdl.comment) {

38 content.push(textOrShortTextOrDescription(mdl.comment, short));

39 if (!short) {

40 content.push(otherCommentTags(mdl.comment));

41 if (mdl.parameters) {

42 content = content.concat(mainCommentParams(mdl.parameters));

43 }

44 }

45 content.push(returns(mdl.comment, false));

46 content.push(commentRemainder(mdl.comment));

47 }

48 return m(<quote>'.hs-item-comment'</quote>, content);

49}

50

51<comment>/**</comment>

52<comment> * Report the item<quote>'s description. This can come in different forms that are all handled here:</comment>

53<comment> * - comment.shortText: <description></comment>

54<comment> * - comment.text: <description></comment>

55<comment> * - comment.tags[{tag:'</quote>description}, text:<description>]</comment>

56<comment> * Any resulting comment will be translated from markdown to html and returned as a `Vnode`.</comment>

57<comment> * @param comment the comment object to parse</comment>

58<comment> * @param short boolean; if true, only the first paragraph of the description will be returned</comment>

59<comment> */</comment>

60function textOrShortTextOrDescription(comment:any, short:boolean):Vnode {

61 let text = (comment.shortText || <quote>''</quote>);

62 if (comment.text) { text += <quote>'\n'</quote>+ (comment.text || <quote>''</quote>); }

63 if (comment.tags) {

64 comment.tags.map((tag:any) => {

65 switch (tag.tag) {

66 case <quote>'shortText'</quote>:

67 case <quote>'description'</quote>: text = `${text}\n${tag.text}`; break;

68 case <quote>'param'</quote>: text = `${text}\n- **${tag.param}**: ${tag.text}`; break;

69 }

70 });

71 }

72 <comment>// search for pattern <example...<file...</example></comment>

73<comment></comment> text = text.replace(/<example[^<]*?(<file[\S\s]*?)<\/example>/gi, short? <quote>''</quote> : example);

74 return m(<quote>'.hs-item-comment-desc'</quote>, prettifyCode(text, short));

75}

76

77<comment>/**</comment>

78<comment> * creates the `returns` message for a function or method.</comment>

79<comment> */</comment>

80function returns(comment:any, short:boolean):Vnode {

81 let text = comment.returns;

82 return m(<quote>'.hs-item-comment-return'</quote>, !text? <quote>''</quote>: [

83 m(<quote>'span.hs-item-comment-tag'</quote>, <quote>'returns:'</quote>),

84 m(<quote>'span.hs-item-comment-text'</quote>, text)

85 ]);

86}

87

88function commentRemainder(comment:any):string|Vnode {

89 return m(<quote>''</quote>, Object.keys(comment).map((tag:any) => {

90 switch(tag) {

91 case <quote>'tags'</quote>: <comment>// already handled</comment>

92<comment></comment> case <quote>'shortText'</quote>: <comment>// already handled</comment>

93<comment></comment> case <quote>'text'</quote>: <comment>// already handled</comment>

94<comment></comment> case <quote>'description'</quote>: <comment>// already handled</comment>

95<comment></comment> case <quote>'returns'</quote>: <comment>// already handled</comment>

96<comment></comment> return <quote>''</quote>;

97 default: return m(<quote>'.hs-item-comment-special'</quote>, [

98 m(<quote>'span.hs-item-comment-tag'</quote>, tag),

99 m(<quote>'span.hs-item-comment-text'</quote>, comment[tag])

100 ]);

101 }

102 }));

103}

104

105function otherCommentTags(comment:any):string|Vnode {

106 return m(<quote>''</quote>, !comment.tags? [] : comment.tags.map((tag:any) => {

107 switch(tag.tag) {

108 case <quote>'description'</quote>: return <quote>''</quote>; <comment>// skip since already handled</comment>

109<comment></comment> default: return m(<quote>'.hs-item-comment-special'</quote>, [

110 m(<quote>'span.hs-item-comment-tag'</quote>, tag.tag),

111 m(<quote>'span.hs-item-comment-text'</quote>, tag.text)

112 ]);

113 }

114 }));

115}

116

117function mainCommentParams(params:any):Vnode {

118 return m(<quote>'.hs-item-comment-params'</quote>, params.map((par:any) =>

119 m(<quote>'.hs-item-comment-param'</quote>, [

120 m(<quote>'span.hs-item-comment-tag'</quote>, par.name+<quote>':'</quote>),

121 m(<quote>'span.hs-item-comment-text'</quote>, !par.comment? <quote>''</quote> :

122 ((par.defaultValue!==undefined)? `[default: ${par.defaultValue}] ` : <quote>''</quote>) + par.comment.text

123 )

124 ])

125 ));

126}

127

128<comment>/**</comment>

129<comment> * finds segments of ``...`` in `comment` and replaces them with a prettified version.</comment>

130<comment> * Currently the function performs operations in this sequence:</comment>

131<comment> * - add indentation for brackets {...}</comment>

132<comment> * - wrap the <code>...</code> part within <pre>...</pre> brackets</comment>

133<comment> * - apply markdown syntax</comment>

134<comment> * - wrap results in a trusted mithril node</comment>

135<comment> * @param comment the comment comment </comment>

136<comment> * @param short only return the first paragraph</comment>

137<comment> */</comment>

138function prettifyCode(comment:string, short:boolean):Vnode {

139<comment>// const indentSpaces = 2;</comment>

140<comment></comment> let result = comment;

141

142 function braceIndenting(text:string): string {

143 let indent = 0;

144 const result = text

145 .substring(6, text.length-7) <comment><comment>// remove `and` </comment></comment>

146<comment></comment> .trim()

147 .replace(/(<)/g, <quote>'<'</quote>).replace(/(>)/g, <quote>'>'</quote>)

148 .split(<quote>'\n'</quote>)

149 .map((l:string) => {

150 let oldIndent = indent;

151 let k = l.trim();

152 indent += Math.max(-1, Math.min(1, k.split(<quote>'{'</quote>).length - k.split(<quote>'}'</quote>).length));

153 indent += Math.max(-1, Math.min(1, k.split(<quote>'['</quote>).length - k.split(<quote>']'</quote>).length));

154 return <quote>'<span class=<quote>"hs-code-indent"</quote>>'</quote>.repeat(((indent < oldIndent)?indent:oldIndent)) + k;

155 })

156 .join(<quote>'\n'</quote>)

157 .trim();

158 return <quote>'

    '</quote> + result + <quote>'

'</quote>;

159 }

160

161 result = result.replace(/`([\S\s]*?)<\/code>/gi, braceIndenting);`

162 return m.trust(markDown(result, short, m.route.get()));

163}

164

`