track.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /**
  2. * @typedef {import('../types.js').CreateTracker} CreateTracker
  3. * @typedef {import('../types.js').TrackCurrent} TrackCurrent
  4. * @typedef {import('../types.js').TrackMove} TrackMove
  5. * @typedef {import('../types.js').TrackShift} TrackShift
  6. */
  7. /**
  8. * Track positional info in the output.
  9. *
  10. * @type {CreateTracker}
  11. */
  12. export function track(config) {
  13. // Defaults are used to prevent crashes when older utilities somehow activate
  14. // this code.
  15. /* c8 ignore next 5 */
  16. const options = config || {}
  17. const now = options.now || {}
  18. let lineShift = options.lineShift || 0
  19. let line = now.line || 1
  20. let column = now.column || 1
  21. return {move, current, shift}
  22. /**
  23. * Get the current tracked info.
  24. *
  25. * @type {TrackCurrent}
  26. */
  27. function current() {
  28. return {now: {line, column}, lineShift}
  29. }
  30. /**
  31. * Define an increased line shift (the typical indent for lines).
  32. *
  33. * @type {TrackShift}
  34. */
  35. function shift(value) {
  36. lineShift += value
  37. }
  38. /**
  39. * Move past some generated markdown.
  40. *
  41. * @type {TrackMove}
  42. */
  43. function move(input) {
  44. // eslint-disable-next-line unicorn/prefer-default-parameters
  45. const value = input || ''
  46. const chunks = value.split(/\r?\n|\r/g)
  47. const tail = chunks[chunks.length - 1]
  48. line += chunks.length - 1
  49. column =
  50. chunks.length === 1 ? column + tail.length : 1 + tail.length + lineShift
  51. return value
  52. }
  53. }