# Mapping line and index to doc positions

**URL:** <https://discuss.prosemirror.net/t/mapping-line-and-index-to-doc-positions/2253>\
**Category:** Uncategorized\
**Created:** [October 2, 2019, 3:15pm UTC](https://discuss.prosemirror.net/t/mapping-line-and-index-to-doc-positions/2253 "2019-10-02T15:15:45Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jameswragg](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/jameswragg/32/1140_2.png) [@jameswragg](https://discuss.prosemirror.net/u/jameswragg)\
**Post date:** [October 2, 2019, 3:15pm UTC](https://discuss.prosemirror.net/t/mapping-line-and-index-to-doc-positions/2253/1 "2019-10-02T15:15:46Z")

</div>

I have an API that returns annotations (spelling/grammar/feedback etc.) to decorate a document. My issue is, it gives back each annotation with a `line` and `index` (line-based) for the annotation positioning.

Any suggestions on how to map these to my ProseMirror doc?

Thanks in advance

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [October 2, 2019, 5:32pm UTC](https://discuss.prosemirror.net/t/mapping-line-and-index-to-doc-positions/2253/2 "2019-10-02T17:32:16Z")

</div>

ProseMirror documents are not, as a rule, divided into lines, so I’m not sure how to interpret this question.

---

<div class="post-metadata">

**Author:** ![jameswragg](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/jameswragg/32/1140_2.png) [@jameswragg](https://discuss.prosemirror.net/u/jameswragg)\
**Post date:** [October 2, 2019, 7:19pm UTC](https://discuss.prosemirror.net/t/mapping-line-and-index-to-doc-positions/2253/3 "2019-10-02T19:19:25Z")

</div>

I’m able to supply the API with a format it wants (array of text) with the following:

```
state.doc
  .textBetween(0, state.doc.content.size, "\n", "\n")
  .split("\n")

```

Its the mapping back of API-provided annotations based on these lines and indexes.

I’m hoping I’m lucky in that the schema is simple, in as much as only having to deal with headings, paragraphs, hard\_breaks and lists (unordered/ordered) so the documents are fairly shallow trees to work with.

Any pointers appreciated.

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [October 3, 2019, 9:51am UTC](https://discuss.prosemirror.net/t/mapping-line-and-index-to-doc-positions/2253/4 "2019-10-03T09:51:24Z")

</div>

Since `textBetween` loses information (non-text structure), I don’t think there’s a way to just map a text position back to a document position. If your schema is extremely simple, or you are willing to do complicated things like matching strings to determine context, you might be able to find a solution, but there’s no simple trick.

---

<div class="post-metadata">

**Author:** ![jameswragg](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/jameswragg/32/1140_2.png) [@jameswragg](https://discuss.prosemirror.net/u/jameswragg)\
**Post date:** [October 3, 2019, 12:20pm UTC](https://discuss.prosemirror.net/t/mapping-line-and-index-to-doc-positions/2253/5 "2019-10-03T12:20:31Z")

</div>

Appreciate the quick responses, thank you.

With your comments in mind, I’ve ditched `textBetween` and taken to bend the rules by passing the API one line of text (trying to ignore lines exist) with string fragments whose index should match the doc positioning like so:

```
getContentAsOffsetText(state) {
  const { doc } = state.tr;

  const injectStr = (sourceStr, index, newStr) => {
    return (
      sourceStr.slice(0, index) +
      newStr +
      sourceStr.slice(index + newStr.length, sourceStr.length)
    );
  };

  let resultStr = new Array(doc.content.size).join(" ");

  doc.descendants((node, pos) => {
    if (node.type.name === "text") {
      resultStr = injectStr(
        resultStr,
        pos,
        doc.textBetween(pos, pos + node.nodeSize)
      );
    }
  });

  return [resultStr];
}

```

Results in something like this which gives me the right index for the typo ‘sstruck’:

```
[" The mouse ran up the clock. The clock sstruck one…"]

```

It seems to be holding up, can you foresee any issues with this approach?

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [October 3, 2019, 7:26pm UTC](https://discuss.prosemirror.net/t/mapping-line-and-index-to-doc-positions/2253/6 "2019-10-03T19:26:12Z")

</div>

Looks reasonable.
