{"version":3,"file":"auto-formatting.cjs","sources":["../../../src/slate/plugins/auto-formatting.ts"],"sourcesContent":["import type { EditorMarks } from \"slate\";\nimport {\n  Editor as SlateEditor,\n  Range as SlateRange,\n  Transforms as SlateTransforms,\n} from \"slate\";\n\nimport { getCharacterBefore } from \"../utils/get-character\";\nimport { getMatchRange } from \"../utils/get-match-range\";\nimport { isEmptyString } from \"../utils/is-empty-string\";\n\ninterface MarkFormatter {\n  type: \"mark\";\n  mark: keyof EditorMarks;\n  character: string;\n}\n\ntype Formatter = MarkFormatter;\n\nconst formatters: Formatter[] = [\n  {\n    type: \"mark\",\n    mark: \"bold\",\n    character: \"*\",\n  },\n  {\n    type: \"mark\",\n    mark: \"italic\",\n    character: \"_\",\n  },\n  {\n    type: \"mark\",\n    mark: \"strikethrough\",\n    character: \"~\",\n  },\n  {\n    type: \"mark\",\n    mark: \"code\",\n    character: \"`\",\n  },\n];\nconst markFormattingCharacters = formatters\n  .filter((formatter) => formatter.type === \"mark\")\n  .map((formatter) => formatter.character);\n\nfunction formatMark<T extends SlateEditor>(\n  editor: T,\n  text: string,\n  formatter: MarkFormatter\n): boolean {\n  if (text !== formatter.character) {\n    return false;\n  }\n\n  const match = getMatchRange(editor, editor.selection!, [formatter.character]);\n\n  // Check if the match exists and is not empty\n  if (!match || SlateRange.isCollapsed(match)) {\n    return false;\n  }\n\n  const formattingCharacter = getCharacterBefore(editor, match);\n\n  // Check if the match is preceded by the formatting character\n  if (\n    !formattingCharacter ||\n    formattingCharacter.text !== formatter.character\n  ) {\n    return false;\n  }\n\n  const beforeCharacter = getCharacterBefore(editor, formattingCharacter.range);\n\n  // Check if the formatting character is preceded by a non-whitespace character (or another formatting character)\n  if (\n    beforeCharacter &&\n    !markFormattingCharacters.includes(beforeCharacter.text) &&\n    !isEmptyString(beforeCharacter.text)\n  ) {\n    return false;\n  }\n\n  const matchText = SlateEditor.string(editor, match);\n\n  // Check if the match has leading/trailing whitespace\n  if (matchText.trim() !== matchText) {\n    return false;\n  }\n\n  // Set the match to the expected mark\n  SlateTransforms.select(editor, match);\n  editor.addMark(formatter.mark, true);\n\n  // Set the selection at the end of the match and reset formatting\n  SlateTransforms.collapse(editor, { edge: \"end\" });\n  editor.removeMark(formatter.mark);\n\n  // Delete the formatting character\n  SlateTransforms.delete(editor, {\n    at: formattingCharacter.range,\n  });\n\n  return true;\n}\n\nexport function withAutoFormatting<T extends SlateEditor>(editor: T): T {\n  const { insertText } = editor;\n\n  editor.insertText = (text, options) => {\n    if (!editor.selection || !SlateRange.isCollapsed(editor.selection)) {\n      return insertText(text, options);\n    }\n\n    let shouldInsertText = true;\n\n    for (const formatter of formatters) {\n      if (formatter.type === \"mark\") {\n        if (formatMark(editor, text, formatter)) {\n          shouldInsertText = false;\n        }\n      }\n    }\n\n    if (shouldInsertText) {\n      insertText(text, options);\n    }\n  };\n\n  return editor;\n}\n"],"names":["getMatchRange","SlateRange","getCharacterBefore","isEmptyString","SlateEditor","SlateTransforms"],"mappings":"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"}