preprocess.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. 'use strict'
  2. var codes = require('./character/codes.js')
  3. var constants = require('./constant/constants.js')
  4. var search = /[\0\t\n\r]/g
  5. function preprocess() {
  6. var start = true
  7. var column = 1
  8. var buffer = ''
  9. var atCarriageReturn
  10. return preprocessor
  11. function preprocessor(value, encoding, end) {
  12. var chunks = []
  13. var match
  14. var next
  15. var startPosition
  16. var endPosition
  17. var code
  18. value = buffer + value.toString(encoding)
  19. startPosition = 0
  20. buffer = ''
  21. if (start) {
  22. if (value.charCodeAt(0) === codes.byteOrderMarker) {
  23. startPosition++
  24. }
  25. start = undefined
  26. }
  27. while (startPosition < value.length) {
  28. search.lastIndex = startPosition
  29. match = search.exec(value)
  30. endPosition = match ? match.index : value.length
  31. code = value.charCodeAt(endPosition)
  32. if (!match) {
  33. buffer = value.slice(startPosition)
  34. break
  35. }
  36. if (
  37. code === codes.lf &&
  38. startPosition === endPosition &&
  39. atCarriageReturn
  40. ) {
  41. chunks.push(codes.carriageReturnLineFeed)
  42. atCarriageReturn = undefined
  43. } else {
  44. if (atCarriageReturn) {
  45. chunks.push(codes.carriageReturn)
  46. atCarriageReturn = undefined
  47. }
  48. if (startPosition < endPosition) {
  49. chunks.push(value.slice(startPosition, endPosition))
  50. column += endPosition - startPosition
  51. }
  52. if (code === codes.nul) {
  53. chunks.push(codes.replacementCharacter)
  54. column++
  55. } else if (code === codes.ht) {
  56. next = Math.ceil(column / constants.tabSize) * constants.tabSize
  57. chunks.push(codes.horizontalTab)
  58. while (column++ < next) chunks.push(codes.virtualSpace)
  59. } else if (code === codes.lf) {
  60. chunks.push(codes.lineFeed)
  61. column = 1
  62. }
  63. // Must be carriage return.
  64. else {
  65. atCarriageReturn = true
  66. column = 1
  67. }
  68. }
  69. startPosition = endPosition + 1
  70. }
  71. if (end) {
  72. if (atCarriageReturn) chunks.push(codes.carriageReturn)
  73. if (buffer) chunks.push(buffer)
  74. chunks.push(codes.eof)
  75. }
  76. return chunks
  77. }
  78. }
  79. module.exports = preprocess