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