How to calculate lines of text in a node?

Hello ProseMirror community!

I’m attempting to find a reliable method to count lines of text in a block node within the context of a plugin.

Assuming the block node has a constant font size and line height, the most straightforward way I can think of is to get the serialized DOM node’s dimensions and divide its height by the line-height value.

I’ve read through the reference manual a fair number of times, in particular model.Node, and I haven’t been to able to find a method to access a node’s corresponding DOM representation when traversing a given document’s node tree, for example in this context:

new Plugin({
  appendTransaction (transactions, oldState, newState) {
    editorState.doc.forEach(function (block, offset, index) {
      console.log('block node', block)
    })
  }
})

I’ve seen a few mentions of people using getBoundingClientRect to get dimensions of a DOM node, but I’m not sure as to how to get to the point where I’d have a DOM node to call that method on when starting with a ProseMirror doc node from an editorState instance.

I’m not asking for anyone to solve this for me, just hoping someone has tackled this before and can point me in the right direction. Please let me know if you have any hints for me. Thank you!

I think I’ve gotten a little closer – it looks like I can get the DOM node using the EditorView.nodeDOM method, and I can get position of a node using Node.descendants.

However, I don’t see any easy way to access the EditorView instance in the context of PluginSpec.appendTransaction. For context, I need to first analyze line count of nodes, and then based on information from that analysis, append a transaction if needed, so appendTransaction seems like the right place to be working here.

It seems only the PluginSpec.view prop can interact with the EditorView. I could try creating some kind of structure where the view plugin method keeps a copy of the EditorView for appendTransaction, but that seems convoluted and potentially problematic.

At this point, the editor view hasn’t been updated yet—the system first computes a new state (which may involve appending transactions), and then updates the view to the new state.

In general, the amount of wrapped lines in a node is potentially dependent on available fonts, window size, zoom level, and css changes, so it’s not something for which you’d be able to compute a fixed, reliable value. Stuff that depends on view layout is not typically stored in EditorState, since that’s considered to be a representation of view-independent state. But of course you can blur these lines a bit, if practical.

What are you planning to use this line count for, though?