index.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. const tab = 9 /* `\t` */
  2. const space = 32 /* ` ` */
  3. /**
  4. * Remove initial and final spaces and tabs at the line breaks in `value`.
  5. * Does not trim initial and final spaces and tabs of the value itself.
  6. *
  7. * @param {string} value
  8. * Value to trim.
  9. * @returns {string}
  10. * Trimmed value.
  11. */
  12. export function trimLines(value) {
  13. const source = String(value)
  14. const search = /\r?\n|\r/g
  15. let match = search.exec(source)
  16. let last = 0
  17. /** @type {Array<string>} */
  18. const lines = []
  19. while (match) {
  20. lines.push(
  21. trimLine(source.slice(last, match.index), last > 0, true),
  22. match[0]
  23. )
  24. last = match.index + match[0].length
  25. match = search.exec(source)
  26. }
  27. lines.push(trimLine(source.slice(last), last > 0, false))
  28. return lines.join('')
  29. }
  30. /**
  31. * @param {string} value
  32. * Line to trim.
  33. * @param {boolean} start
  34. * Whether to trim the start of the line.
  35. * @param {boolean} end
  36. * Whether to trim the end of the line.
  37. * @returns {string}
  38. * Trimmed line.
  39. */
  40. function trimLine(value, start, end) {
  41. let startIndex = 0
  42. let endIndex = value.length
  43. if (start) {
  44. let code = value.codePointAt(startIndex)
  45. while (code === tab || code === space) {
  46. startIndex++
  47. code = value.codePointAt(startIndex)
  48. }
  49. }
  50. if (end) {
  51. let code = value.codePointAt(endIndex - 1)
  52. while (code === tab || code === space) {
  53. endIndex--
  54. code = value.codePointAt(endIndex - 1)
  55. }
  56. }
  57. return endIndex > startIndex ? value.slice(startIndex, endIndex) : ''
  58. }