simian 0.1.1

A command-line tool for exploring and implementing Machine Learning algorithms in Rust.
Documentation
import { Editor, Element, Transforms } from 'slate'

//import { isInsideElement } from "@/ui/editor/utils";
import { TextMark } from '../types'
import { isInsideMark } from '../utils'
import { applyMarkOnHotKey } from '../utils/keyboard'

export const CodeMark: TextMark = (props) => {
  return (
    <code
      {...props}
      className="
        rounded-md px-1.5 py-0.5 text-sm font-mono 
        bg-zinc-100 text-zinc-800 
        dark:bg-zinc-800 dark:text-zinc-100
        border border-zinc-200 dark:border-zinc-700
      "
    />
  )
}

/**
 * Handle key down to detect when we should leave the code mark.
 */
CodeMark.onKeyDown = ({ editor, selection }, evt) => {
  if (applyMarkOnHotKey(editor, evt, 'mod+`', 'code')) {
    return true
  }

  if (selection?.isCollapsed) {
    // Check if we are inside the code mark.
    const marks = Editor.marks(editor)

    if (marks?.code) {
      switch (evt.key) {
        // User hits Enter => Leave the code mark and go to next line.
        case 'Enter': {
          evt.preventDefault()
          Editor.removeMark(editor, 'code')
          Editor.insertBreak(editor)
          break
        }

        // User hits Backspace at the very start of the code mark => remove the mark.
        case 'Backspace': {
          if (selection.anchor.offset === 0) {
            Editor.removeMark(editor, 'code')
          }

          break
        }

        default: {
          break
        }
      }
    }
  }

  return false
}

/**
 * Handle code mark markdown shortcut.
 */
CodeMark.insertText = ({ editor, selection }, text) => {
  if (text === '`' && selection?.isCollapsed) {
    // Skip detection if we are inside some special elements.
    if (
      //isInsideElement(editor, ["code-block", "latex-block", "latex-inline"]) ||
      isInsideMark(editor, 'code')
    ) {
      return false
    }

    const { anchor } = selection
    const block = Editor.above(editor, {
      match: (n) => Element.isElement(n) && Editor.isBlock(editor, n),
    })
    const path = block ? block[1] : []
    const start = Editor.start(editor, path)
    const rangeBefore = { anchor, focus: start }
    const beforeText = Editor.string(editor, rangeBefore)

    // Regex to match: `content
    const match = beforeText.match(/`([^`]+)$/)

    if (match) {
      const [fullMatch, content] = match

      // Calculate the start point of the `
      const startPoint = {
        path: anchor.path,
        offset: anchor.offset - fullMatch.length,
      }

      // 1. Select the range to replace: `content
      Transforms.select(editor, { anchor: startPoint, focus: anchor })

      // 2. Insert the node directly at the selection.
      // Without the 'at' property, Slate replaces the selection
      // and moves the cursor to the end of the insertion.
      Transforms.insertNodes(editor, { text: content, code: true })

      // 3. Clear the mark for the next character
      Editor.removeMark(editor, 'code')

      return true
    }
  }
  return false
}