summarize.js 2.2 KB

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