Short version: If I have a schema that contains lines (<p>
) inside “blocks” (<div>
), what command/code can I use to create a new “block”, or make it so that hitting Enter on a blank line creates one?
Long version: I’m trying to use ProseMirror to replace what is currently just a textarea. In the textarea, we’ve been following the convention that a blank line (two consecutive line breaks) separates paragraphs (blocks) of text. (Line breaks are significant because the editor is meant for proofreading a scanned page.)
After my first attempt where I tried to model the document/page as “paragraphs” (<p>
) containing inline hard breaks (<br>
), I decided I prefer instead to have nodes in the tree for individual lines (so <p>
), with the “paragraphs”/“blocks” (now <div>
s enclosing the <p>
lines) containing them, with a schema like:
const schema = new Schema({
nodes: {
// The document (page) is a sequence of blocks.
doc: { content: 'block*' },
// A block is a sequence of lines. Represented in the DOM as a `<div>`.
block: {
content: "line+",
toDOM() { return ['div', 0] as DOMOutputSpec; },
},
// A line contains text. Represented in the DOM as a `<p>` element.
line: {
content: 'text*',
parseDOM: [{ tag: 'p' }],
toDOM() { return ['p', 0] as DOMOutputSpec; },
},
text: { inline: true },
},
});
But that’s as far as I’ve got, because now I’m not sure how to work with the “paragraphs”/“blocks” (the <div>
s), specifically how to create a new block. So I’m looking for an existing function, or some hints about how to write code that does (I imagine) something like:
- Find the enclosing block (
<div>
) around the current cursor / selection, - Create and append a new sibling block,
- Move selection to inside the new block.
And then I suppose I could also bind Enter to look at the current line and call the above createNewBlock
when the current line is empty, so that hitting Enter on a blank line will start a new block.