markdown.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /**
  2. * Translate doclet descriptions from Markdown into HTML.
  3. *
  4. * @module plugins/markdown
  5. */
  6. const env = require('jsdoc/env');
  7. const config = env.conf.markdown || {};
  8. const defaultTags = [
  9. 'author',
  10. 'classdesc',
  11. 'description',
  12. 'exceptions',
  13. 'params',
  14. 'properties',
  15. 'returns',
  16. 'see',
  17. 'summary'
  18. ];
  19. const hasOwnProp = Object.prototype.hasOwnProperty;
  20. const parse = require('jsdoc/util/markdown').getParser();
  21. let tags = [];
  22. let excludeTags = [];
  23. function shouldProcessString(tagName, text) {
  24. let shouldProcess = true;
  25. // we only want to process `@author` and `@see` tags that contain Markdown links
  26. if ( (tagName === 'author' || tagName === 'see') && !text.includes('[') ) {
  27. shouldProcess = false;
  28. }
  29. return shouldProcess;
  30. }
  31. /**
  32. * Process the markdown source in a doclet. The properties that should be processed are
  33. * configurable, but always include "author", "classdesc", "description", "exceptions", "params",
  34. * "properties", "returns", and "see". Handled properties can be bare strings, objects, or arrays
  35. * of objects.
  36. */
  37. function process(doclet) {
  38. tags.forEach(tag => {
  39. if ( !hasOwnProp.call(doclet, tag) ) {
  40. return;
  41. }
  42. if (typeof doclet[tag] === 'string' && shouldProcessString(tag, doclet[tag]) ) {
  43. doclet[tag] = parse(doclet[tag]);
  44. }
  45. else if ( Array.isArray(doclet[tag]) ) {
  46. doclet[tag].forEach((value, index, original) => {
  47. const inner = {};
  48. inner[tag] = value;
  49. process(inner);
  50. original[index] = inner[tag];
  51. });
  52. }
  53. else if (doclet[tag]) {
  54. process(doclet[tag]);
  55. }
  56. });
  57. }
  58. // set up the list of "tags" (properties) to process
  59. if (config.tags) {
  60. tags = config.tags.slice();
  61. }
  62. // set up the list of default tags to exclude from processing
  63. if (config.excludeTags) {
  64. excludeTags = config.excludeTags.slice();
  65. }
  66. defaultTags.forEach(tag => {
  67. if (!excludeTags.includes(tag) && !tags.includes(tag)) {
  68. tags.push(tag);
  69. }
  70. });
  71. exports.handlers = {
  72. /**
  73. * Translate Markdown syntax in a new doclet's description into HTML. Is run
  74. * by JSDoc 3 whenever a "newDoclet" event fires.
  75. */
  76. newDoclet({doclet}) {
  77. process(doclet);
  78. }
  79. };