How to nest (indent) a section

My schema has section: { content: ‘section_title (paragraph)* section*’ } section_title: { content: ‘text*’ } (renderered as <-h1->)

In my document, I have doc: [section, section]

when the cursor is on the title of the second, I’d like to indent (via nesting) the second section as a child of the first: doc: [section: [section]]

My first attempt–wrapping the second section in a section and then joining the result to the first, didn’t get off the ground because my findWrapping() is returning null. I’m pretty confident that I have the range set correctly.

What would be the best way to perform this action? (I’ll also want to do the inverse).

That’s because, without an additonal title, wrapping the section in another section would violate the schema.

You’ll have to do something like creating a ReplaceAround step that deletes the closing token of the first section and adds an additional closing token after the second section.

I wondered if it would involve that. I’m still wrapping my head around some of this. I guess it’s time to find out what a Slice is. This is a pretty awesome library, by the way.

(I promise I’m not being lazy about this. I’ve read the docs on ReplaceAroundStep, ReplaceStep, and Slice to get a bead on this.)

I’ve got a slice for the 2nd section, which I think is the slice I need to pass to ReplaceAroundStep constructor. It’s the pair of from/to values that I am struggling with. Given that the intent is to make the 2nd section a child–not a sibling–of the 1st section, what would the constructor look like when the cursor is at some arbitrary point within the 2nd section_title’s text?

Screenshot from 2020-06-26 17-10-06 Screenshot from 2020-06-26 17-09-14

You should think of openStart/openEnd as chopping off a number of open tokens at the start or close tokens at the end, from the fragment you pass in. So in this case, you’ll want to insert a section close token and insert the existing section inside it. The step should (I think) look like (where start and end are the start and end of the section to wrap)

new ReplaceAroundStep(
  start - 1, // cover the end of the prev section
  start, // The 'gap' covers the section that must be wrapped
  new Slice(sectionNodeType.create(), 1, 0), // Section that's open at the start
  0, // Insert the gap content at the start of the slice

Thanks, mate. You are exceedingly helpful and patient. I just sent beer money. I hope it wasn’t a donation to the New York Times.

I’ve gleaned a lot from your tip as well as stepping through and studying the code. The above doesn’t yet work, but I’ve had to make some tiny mods. Let me make sure I have the proper understanding. Slice(sectionNodeType.create()...) wouldn’t pass TS, but Slice(sectionNodeType.create().content) did compile.

From the screen shot above, start = 44 and end = 86. Is that correct? The gap contents created by the step constructor are indeed the correct contents–but I’ve found that I can bumble the end points here and still end up with the same content. That is what I am passing to the constructor of ReplaceAroundStep per your recommendation. I am getting this error:

The openSlice is 1, but the slice is empty.

Oh, right, I forgot a Fragment.from(...) around the section node. That might help.

That did it! Thanks for your help.

May I ask what tool could build such an position graph like this one? Thanks a ton!

update: I find it. GitHub - d4rkr00t/prosemirror-dev-tools: Developer Tools for ProseMirror

Beware that the position graphs in prosemirror-dev-tools can be a bit misleading—for example, in the document above, the first section starts at position 0, but the tool shows a 1 before it.

Thanks @marijn , yeah that’s a gotcha.