index.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. 'use strict';
  2. var error = require('pug-error');
  3. module.exports = stripComments;
  4. function unexpectedToken(type, occasion, filename, line) {
  5. var msg = '`' + type + '` encountered when ' + occasion;
  6. throw error('UNEXPECTED_TOKEN', msg, {filename: filename, line: line});
  7. }
  8. function stripComments(input, options) {
  9. options = options || {};
  10. // Default: strip unbuffered comments and leave buffered ones alone
  11. var stripUnbuffered = options.stripUnbuffered !== false;
  12. var stripBuffered = options.stripBuffered === true;
  13. var filename = options.filename;
  14. var out = [];
  15. // If we have encountered a comment token and are not sure if we have gotten
  16. // out of the comment or not
  17. var inComment = false;
  18. // If we are sure that we are in a block comment and all tokens except
  19. // `end-pipeless-text` should be ignored
  20. var inPipelessText = false;
  21. return input.filter(function(tok) {
  22. switch (tok.type) {
  23. case 'comment':
  24. if (inComment) {
  25. unexpectedToken(
  26. 'comment',
  27. 'already in a comment',
  28. filename,
  29. tok.line
  30. );
  31. } else {
  32. inComment = tok.buffer ? stripBuffered : stripUnbuffered;
  33. return !inComment;
  34. }
  35. case 'start-pipeless-text':
  36. if (!inComment) return true;
  37. if (inPipelessText) {
  38. unexpectedToken(
  39. 'start-pipeless-text',
  40. 'already in pipeless text mode',
  41. filename,
  42. tok.line
  43. );
  44. }
  45. inPipelessText = true;
  46. return false;
  47. case 'end-pipeless-text':
  48. if (!inComment) return true;
  49. if (!inPipelessText) {
  50. unexpectedToken(
  51. 'end-pipeless-text',
  52. 'not in pipeless text mode',
  53. filename,
  54. tok.line
  55. );
  56. }
  57. inPipelessText = false;
  58. inComment = false;
  59. return false;
  60. // There might be a `text` right after `comment` but before
  61. // `start-pipeless-text`. Treat it accordingly.
  62. case 'text':
  63. return !inComment;
  64. default:
  65. if (inPipelessText) return false;
  66. inComment = false;
  67. return true;
  68. }
  69. });
  70. }