import { InputRule } from 'prosemirror-inputrules' import { MarkType } from 'prosemirror-model' import getMarksBetween from '../helpers/getMarksBetween' export default function (regexp: RegExp, markType: MarkType, getAttributes?: Function): InputRule { return new InputRule(regexp, (state, match, start, end) => { const attributes = getAttributes instanceof Function ? getAttributes(match) : getAttributes const { tr } = state const captureGroup = match[match.length - 1] const fullMatch = match[0] let markEnd = end if (captureGroup) { const startSpaces = fullMatch.search(/\S/) const textStart = start + fullMatch.indexOf(captureGroup) const textEnd = textStart + captureGroup.length const excludedMarks = getMarksBetween(start, end, state) .filter(item => { // TODO: PR to add excluded to MarkType // @ts-ignore const { excluded } = item.mark.type return excluded.find((type: MarkType) => type.name === markType.name) }) .filter(item => item.to > textStart) if (excludedMarks.length) { return null } if (textEnd < end) { tr.delete(textEnd, end) } if (textStart > start) { tr.delete(start + startSpaces, textStart) } markEnd = start + startSpaces + captureGroup.length tr.addMark(start + startSpaces, markEnd, markType.create(attributes)) tr.removeStoredMark(markType) } return tr }) }