docblock.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. /**
  2. * Helper functions to work with docblock comments.
  3. */
  4. const DOCLET_PATTERN = /^@(\w+)(?:$|\s((?:[^](?!^@\w))*))/gim;
  5. function parseDocblock(str) {
  6. // Does not use \s in the regex as this would match also \n and conflicts
  7. // with windows line endings.
  8. return str.replace(/^[ \t]*\*[ \t]?/gm, '').trim();
  9. }
  10. const DOCBLOCK_HEADER = /^\*\s/;
  11. /**
  12. * Given a path, this function returns the closest preceding docblock if it
  13. * exists.
  14. */
  15. export function getDocblock(path, trailing = false) {
  16. let comments = [];
  17. if (trailing && path.node.trailingComments) {
  18. comments = path.node.trailingComments.filter((comment) => comment.type === 'CommentBlock' && DOCBLOCK_HEADER.test(comment.value));
  19. }
  20. else if (path.node.leadingComments) {
  21. comments = path.node.leadingComments.filter((comment) => comment.type === 'CommentBlock' && DOCBLOCK_HEADER.test(comment.value));
  22. }
  23. if (comments.length > 0) {
  24. return parseDocblock(comments[comments.length - 1].value);
  25. }
  26. return null;
  27. }
  28. /**
  29. * Given a string, this functions returns an object with doclet names as keys
  30. * and their "content" as values.
  31. */
  32. export function getDoclets(str) {
  33. const doclets = Object.create(null);
  34. let match;
  35. while ((match = DOCLET_PATTERN.exec(str))) {
  36. doclets[match[1]] = match[2] || true;
  37. }
  38. return doclets;
  39. }