pos-to-linecolumn.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // pos-to-linecolumn.js
  2. // MIT licensed, see LICENSE file
  3. // Copyright (c) 2014-2015 Olov Lassus <olov.lassus@gmail.com>
  4. "use strict";
  5. const assert = require("assert");
  6. module.exports = PosToLineColumn;
  7. function PosToLineColumn(str) {
  8. if (!(this instanceof PosToLineColumn)) {
  9. throw new Error("PosToLineColumn requires new");
  10. }
  11. str = String(str);
  12. const newlines = [];
  13. let pos = -1;
  14. while ((pos = str.indexOf("\n", pos + 1)) >= 0) {
  15. newlines.push(pos);
  16. }
  17. let line = 1;
  18. let column = 0;
  19. const columns = [];
  20. const lines = [];
  21. let i;
  22. let j = 0;
  23. for (i = 0; i < str.length; i++) {
  24. columns[i] = column;
  25. lines[i] = line;
  26. if (i === newlines[j]) {
  27. ++j;
  28. ++line;
  29. column = 0;
  30. } else {
  31. ++column;
  32. }
  33. }
  34. // add extra entry to support pos === str.length
  35. columns[i] = column;
  36. lines[i] = line;
  37. this.len = str.length;
  38. this.columns = columns;
  39. this.lines = lines;
  40. }
  41. PosToLineColumn.prototype.toLine = function(pos) {
  42. assert(pos >= 0 && pos <= this.len);
  43. return this.lines[pos];
  44. };
  45. PosToLineColumn.prototype.toColumn = function(pos) {
  46. assert(pos >= 0 && pos <= this.len);
  47. return this.columns[pos];
  48. };
  49. PosToLineColumn.prototype.toLineColumn = function(pos) {
  50. return {
  51. line: this.toLine(pos),
  52. column: this.toColumn(pos),
  53. };
  54. };
  55. /*
  56. const tst = "asdf\n" +
  57. "abc\n" +
  58. "d\n" +
  59. "\n\n" +
  60. "efghi a\r\n" +
  61. "x";
  62. const instance = new PosToLineColumn(tst);
  63. console.dir(instance.toLineColumn(0));
  64. console.dir(instance.toLineColumn(tst.length));
  65. */