BulletList to TodoList conversion

Hi. I’m trying to convert - [ ] init a todo list. The problem that - is converted to a bullet_list, which can contain only list_item+.

Here is the input rule:

new InputRule(/^\[([ |x])\] $/, function (state, match, start, end) {
  const { $from } = state.selection;
  if (
    $from.depth >= 3 &&
    $from.node(-1).type.name === 'list_item' &&
    $from.node(-2).type.name === 'bullet_list' &&
    $from.index(-1) === 0 // The cursor is at the first child (paragraph) of this list item.
  ) {
    const attrs = { done: match[1] === 'x' };
    return state.tr
      .delete(start, end)
      .setNodeMarkup(
        $from.before(-1),
        state.schema.nodes.todo_item,
        attrs
      )
      .setNodeMarkup($from.before(-2), state.schema.nodes.todo_list);
  }
  return null;
}),

And here is the problem I’m getting:

Uncaught TransformError: Invalid content for node bullet_list

Could you, please, describe the steps how to convert ordered_list into a todo_list in a bulk?

The easiest way would be to replace the entire ordered list with a bullet list node, I think. When there’s only a single item, you could also create a ReplaceAroundStep that replaces the opening and closing tokens for the ordered list and list item with bullet list and bullet item tokens, but I’m not sure that’s worth the bother, since when the input rule kicks in you are probably dealing with an empty list, and there’s no real value in avoiding replacements of the list item content.

Thanks, for a quick answer.

Here is the solution:

new InputRule(/^\[([ |x])\] $/, function (state, match, start, end) {
  const { $from } = state.selection;
  if (
    $from.depth >= 3 &&
    $from.node(-1).type.name === 'list_item' &&
    $from.node(-2).type.name === 'bullet_list' &&
    $from.index(-1) === 0 // The cursor is at the first child (paragraph) of this list item.
  ) {
    const attrs = { done: match[1] === 'x' };
    const node = type.create(
      {},
      state.schema.nodes.todo_item.create(
        attrs,
        state.schema.nodes.paragraph.create()
      )
    );

    const tr = state.tr
      .delete($from.before(-2), $from.end())
      .insert($from.before(-2), node);

    return tr.setSelection(TextSelection.create(tr.doc, start));
    // return state.tr
    //   .delete(start, end)
    //   .setNodeMarkup(
    //     $from.before(-1),
    //     state.schema.nodes.todo_item,
    //     attrs
    //   )
    //   .setNodeMarkup($from.before(-2), state.schema.nodes.todo_list);
  }
  return null;
}),

Is it valid in terms of ProseMirror? Thanks in advance.