aboutsummaryrefslogtreecommitdiff
path: root/js/ansi/newlines.js
blob: 4e37a0adbc1a95aca006587fceda9a56980867ef (plain)
  1. /**
  2.  * Accepts any node Stream instance and hijacks its "write()" function,
  3. * so that it can count any newlines that get written to the output.
  4. *
  5. * When a '\n' byte is encountered, then a "newline" event will be emitted
  6. * on the stream, with no arguments. It is up to the listeners to determine
  7. * any necessary deltas required for their use-case.
  8. *
  9. * Ex:
  10. *
  11. * var cursor = ansi(process.stdout)
  12. * , ln = 0
  13. * process.stdout.on('newline', function () {
  14. * ln++
  15. * })
  16. */
  17. /**
  18. * Module dependencies.
  19. */
  20. var assert = require('assert')
  21. var NEWLINE = '\n'.charCodeAt(0)
  22. function emitNewlineEvents (stream) {
  23. if (stream._emittingNewlines) {
  24. // already emitting newline events
  25. return
  26. }
  27. var write = stream.write
  28. stream.write = function (data) {
  29. // first write the data
  30. var rtn = write.apply(stream, arguments)
  31. if (stream.listeners('newline').length > 0) {
  32. var len = data.length
  33. , i = 0
  34. // now try to calculate any deltas
  35. if (typeof data == 'string') {
  36. for (; i<len; i++) {
  37. processByte(stream, data.charCodeAt(i))
  38. }
  39. } else {
  40. // buffer
  41. for (; i<len; i++) {
  42. processByte(stream, data[i])
  43. }
  44. }
  45. }
  46. return rtn
  47. }
  48. stream._emittingNewlines = true
  49. }
  50. module.exports = emitNewlineEvents
  51. /**
  52. * Processes an individual byte being written to a stream
  53. */
  54. function processByte (stream, b) {
  55. assert.equal(typeof b, 'number')
  56. if (b === NEWLINE) {
  57. stream.emit('newline')
  58. }
  59. }