index.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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', 'already in a comment', filename, tok.line
  27. );
  28. } else {
  29. inComment = tok.buffer ? stripBuffered : stripUnbuffered;
  30. return !inComment;
  31. }
  32. case 'start-pipeless-text':
  33. if (!inComment) return true;
  34. if (inPipelessText) {
  35. unexpectedToken(
  36. 'start-pipeless-text', 'already in pipeless text mode',
  37. filename, tok.line
  38. );
  39. }
  40. inPipelessText = true;
  41. return false;
  42. case 'end-pipeless-text':
  43. if (!inComment) return true;
  44. if (!inPipelessText) {
  45. unexpectedToken(
  46. 'end-pipeless-text', 'not in pipeless text mode',
  47. filename, tok.line
  48. );
  49. }
  50. inPipelessText = false;
  51. inComment = false;
  52. return false;
  53. // There might be a `text` right after `comment` but before
  54. // `start-pipeless-text`. Treat it accordingly.
  55. case 'text':
  56. return !inComment;
  57. default:
  58. if (inPipelessText) return false;
  59. inComment = false;
  60. return true;
  61. }
  62. });
  63. }