UNPKG

2.27 kBJavaScriptView Raw
1/**
2 * This plugin creates a summary tag, if missing, from the first sentence in the description.
3 *
4 * @module plugins/summarize
5 */
6'use strict';
7
8exports.handlers = {
9 /**
10 * Autogenerate summaries, if missing, from the description, if present.
11 */
12 newDoclet: function(e) {
13 var endTag;
14 var tags;
15 var stack;
16
17 // If the summary is missing, grab the first sentence from the description
18 // and use that.
19 if (e.doclet && !e.doclet.summary && e.doclet.description) {
20 // The summary may end with `.$`, `. `, or `.<` (a period followed by an HTML tag).
21 e.doclet.summary = e.doclet.description.split(/\.$|\.\s|\.</)[0];
22 // Append `.` as it was removed in both cases, or is possibly missing.
23 e.doclet.summary += '.';
24
25 // This is an excerpt of something that is possibly HTML.
26 // Balance it using a stack. Assume it was initially balanced.
27 tags = e.doclet.summary.match(/<[^>]+>/g) || [];
28 stack = [];
29
30 tags.forEach(function(tag) {
31 var idx = tag.indexOf('/');
32
33 if (idx === -1) {
34 // start tag -- push onto the stack
35 stack.push(tag);
36 } else if (idx === 1) {
37 // end tag -- pop off of the stack
38 stack.pop();
39 }
40
41 // otherwise, it's a self-closing tag; don't modify the stack
42 });
43
44 // stack should now contain only the start tags that lack end tags,
45 // with the most deeply nested start tag at the top
46 while (stack.length > 0) {
47 // pop the unmatched tag off the stack
48 endTag = stack.pop();
49 // get just the tag name
50 endTag = endTag.substring(1, endTag.search(/[ >]/));
51 // append the end tag
52 e.doclet.summary += '</' + endTag + '>';
53 }
54
55 // and, finally, if the summary starts and ends with a <p> tag, remove it; let the
56 // template decide whether to wrap the summary in a <p> tag
57 e.doclet.summary = e.doclet.summary.replace(/^<p>(.*)<\/p>$/i, '$1');
58 }
59 }
60};