comments.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*!
  2. * extract-comments <https://github.com/jonschlinkert/extract-comments>
  3. *
  4. * Copyright (c) 2014 Jon Schlinkert, contributors.
  5. * Licensed under the MIT license.
  6. */
  7. 'use strict';
  8. var extract = require('esprima-extract-comments');
  9. var extend = require('extend-shallow');
  10. var define = require('define-property');
  11. var Context = require('./context');
  12. var Block = require('./block');
  13. var Line = require('./line');
  14. /**
  15. * If you need to customize the generated comment objects, you
  16. * can create an instance of `Comments`:
  17. *
  18. * ```js
  19. * var extract = require('extract-comments');
  20. * var Comments = extract.Comments;
  21. * var comments = new Comments(options);
  22. * ```
  23. * @param {String} `string`
  24. * @param {Object} `options`
  25. * @param {Object} `options.first` Return the first comment only
  26. * @param {Object} `options.banner` alias for `options.first`
  27. * @param {Function} `fn` Optionally pass a transform function to call on each token (comment) in the AST.
  28. * @return {String}
  29. * @api public
  30. */
  31. function Comments(options, fn) {
  32. this.options = extend({type: 'block'}, options);
  33. this.transform = fn;
  34. this.comments = [];
  35. }
  36. Comments.prototype.extract = function(str) {
  37. if (typeof str !== 'string') {
  38. throw new TypeError('expected a string');
  39. }
  40. define(this, 'input', str);
  41. var opts = this.options;
  42. var ast = [];
  43. try {
  44. ast = extract(this.input);
  45. } catch (err) {
  46. if (opts.silent !== true) {
  47. throw err;
  48. }
  49. }
  50. var strip = opts.stripProtected;
  51. var keep = opts.keepProtected;
  52. if (typeof keep === 'undefined' && typeof strip === 'undefined') {
  53. strip = false;
  54. } else if (typeof keep !== 'undefined') {
  55. strip = !keep;
  56. }
  57. var len = ast.length;
  58. var idx = -1;
  59. while (++idx < len) {
  60. var token = ast[idx];
  61. token.type = token.type.toLowerCase();
  62. if (typeof this.options.filter === 'function') {
  63. if (this.options.filter(token)) {
  64. continue;
  65. }
  66. }
  67. if (/^\*?!/.test(token.value) && strip === false) {
  68. continue;
  69. }
  70. if (token.type === 'block' && opts.block !== false) {
  71. var comment = new Block(str, token, opts);
  72. if (opts.context !== false) {
  73. comment.code = new Context(str, comment, opts);
  74. }
  75. if (typeof this.transform === 'function') {
  76. var res = this.transform(comment, this.options);
  77. if (res) comment = res;
  78. }
  79. this.comments.push(comment);
  80. }
  81. if (token.type === 'line' && opts.line !== false) {
  82. this.comments.push(new Line(str, token, opts));
  83. }
  84. if ((opts.first || opts.banner) && this.comments.length === 1) {
  85. break;
  86. }
  87. }
  88. return this;
  89. };
  90. /**
  91. * Expose `Comments` constructor, to
  92. * allow plugins to be registered.
  93. */
  94. module.exports = Comments;