1 | /**
|
2 | * This plugin creates a summary tag, if missing, from the first sentence in the description.
|
3 | *
|
4 | * @module plugins/summarize
|
5 | */
|
6 | ;
|
7 |
|
8 | exports.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 | };
|