如何在 slate js 中为特定关键字着色

how to color specific keywords in slate js

试图让单词“hello”以不同的颜色出现,几乎使用了示例中的示例 1:1,但无法正常工作。

每当我输入“你好”时,文字开始出现两次。

我的代码:

import { Editable, Slate, withReact } from "slate-react";
import React, { useMemo, useState } from "react";
import { Text, createEditor } from "slate";

import { withHistory } from "slate-history";

const log = (x) => {
  console.log(x);
  return x;
};
const tokenize = (text) =>
  text
    .split(/(\s+)/)
    .map((x) => (x === "hello" ? { content: x, type: "keyword" } : x));

const getLength = (token) =>
  typeof token === "string"
    ? token.length
    : typeof token.content === "string"
    ? token.content.length
    : token.content.reduce((l, t) => l + getLength(t), 0);

const Leaf = ({ attributes, children, leaf }) => (
  <span
    style={{ color: log(leaf).keyword ? "green" : "black" }}
    {...attributes}
  >
    {log(children)}
  </span>
);

const CodeEditor = () => {
  const [value, setValue] = useState([
    {
      type: "paragraph",
      children: [
        {
          text: "",
        },
      ],
    },
  ]);
  const editor = useMemo(() => withHistory(withReact(createEditor())), []);
  return (
    <Slate editor={editor} value={value} onChange={(value) => setValue(value)}>
      <Editable
        decorate={decorate}
        renderLeaf={(props) => <Leaf {...props} />}
        placeholder="Write some code..."
      />
    </Slate>
  );
};

const decorate = ([node, path]) => {
  if (!Text.isText(node)) {
    return [];
  }
  const ranges = [];
  const tokens = tokenize(node.text);
  let start = 0;
  for (const token of tokens) {
    const end = start + getLength(token);
    if (typeof token !== "string") {
      ranges.push({
        [token.type]: true,
        anchor: { path, offset: start },
        focus: { path, offset: end },
      });
    }
    start = end;
  }
  return ranges;
};

export default CodeEditor;

代码很好,这是 https://github.com/ianstormtaylor/slate/pull/4556 中修复的库中的错误。