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
}