# All files preprocess.js

100% Statements 74/74
98.08% Branches 51/52
100% Functions 7/7
100% Lines 68/68

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    3x

    4x

    50x
    50x
    259x
    259x
    259x
    259x
    259x
    259x
    259x

    259x
    240x
    103x
    103x

    137x
    137x

    240x
    27x

    240x
    168x
    1x

    72x
    3x
    2x

    237x
    237x
    429x
    429x
    11x
    11x
    418x
    15x
    403x
    25x
    378x
    213x

    165x

    237x
    237x

    237x
    237x
    569x
    569x
    569x
    4x
    565x
    3x
    562x

    82x

    237x
    237x

    256x

    47x

    253x
    61x
    61x
    61x

    192x

    253x

    47x
    239x

    192x
    192x
    192x
    168x
    168x

    47x

     function indentError(input, l, p) {
      throw input.error('Mixed tabs and spaces are not allowed', l, p + 1)
    }

    module.exports = function preprocess(input, lines) {
      let indentType
      let prevNumber = 0
      let parts = lines.map(line => {
        let lastComma = false
        let comment = false
        let number = prevNumber + 1
        let atrule = false
        let indent = ''
        let tokens = []
        let colon = false

        if (line.length > 0) {
          if (line[0][0] === 'space') {
            indent = line[0][1]
            tokens = line.slice(1)
          } else {
            indent = ''
            tokens = line
          }

          if (!indentType && indent.length) {
            indentType = indent[0] === ' ' ? 'space' : 'tab'
          }
          if (indentType === 'space') {
            if (indent.includes('\t')) {
              indentError(input, number, indent.indexOf('\t'))
            }
          } else if (indentType === 'tab') {
            if (indent.includes(' ')) {
              indentError(input, number, indent.indexOf(' '))
            }
          }

          Eif (tokens.length) {
            for (let i = tokens.length - 1; i >= 0; i--) {
              let type = tokens[i][0]
              if (type === ',') {
                lastComma = true
                break
              } else if (type === 'space') {
                continue
              } else if (type === 'comment') {
                continue
              } else if (type === 'newline') {
                continue
              } else {
                break
              }
            }
            comment = tokens[0][0] === 'comment'
            atrule = tokens[0][0] === 'at-word'

            let brackets = 0
            for (let i = 0; i < tokens.length - 1; i++) {
              let type = tokens[i][0]
              let next = tokens[i + 1][0]
              if (type === '(') {
                brackets += 1
              } else if (type === ')') {
                brackets -= 1
              } else if (
                type === ':' &&
                brackets === 0 &&
                (next === 'space' || next === 'newline')
              ) {
                colon = true
              }
            }
          }

          let last = tokens[tokens.length - 1]
          if (last && last[0] === 'newline') prevNumber = last[2]
        }

        return {
          number,
          indent,
          colon,
          tokens,
          atrule,
          comment,
          lastComma,
          before: ''
        }
      })

      parts = parts.reduceRight(
        (all, i) => {
          if (!i.tokens.length || i.tokens.every(j => j[0] === 'newline')) {
            let prev = all[0]
            let before = i.indent + i.tokens.map(j => j[1]).join('')
            prev.before = before + prev.before
          } else {
            all.unshift(i)
          }
          return all
        },
        [{ end: true, before: '' }]
      )

      parts.forEach((part, i) => {
        if (i === 0) return

        let prev = parts[i - 1]
        let last = prev.tokens[prev.tokens.length - 1]
        if (last && last[0] === 'newline') {
          part.before = last[1] + part.before
          prev.tokens.pop()
        }
      })

      return parts
    }