启用复选框并在更改复选框时更改 Markdown

Make checkboxes enabled and change markdown when changing checkbox

提问人:dsadsadsadas dsadasdasda 提问时间:11/16/2023 最后编辑:isherwooddsadsadsadas dsadasdasda 更新时间:11/16/2023 访问量:26

问:

我有这个基本代码,可以将输入的 md 呈现为 html,默认情况下,所有复选框都被禁用,即使我在浏览器中使用开发人员菜单启用它们,它们仍然无法选中。如何使它们可检查,以及如何根据更改这些复选框状态的“预览模式”更改 Markdown?

我尝试使用 Rehype 库,但进展不顺利,这就是我问这个问题的原因。

import { createElement } from "react";
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkGfm from "remark-gfm";
import remarkReact from "remark-react/lib";
import { PreviewWindow } from "./style";
import RemarkCode from "./remarkCode";
import { defaultSchema } from "hast-util-sanitize";
import "github-markdown-css/github-markdown.css";
import { ViewMode } from "../types";
import remarkRehype from "remark-rehype";
import rehypeDocument from "rehype-document";
import rehypeFormat from "rehype-format";
import rehypeStringify from "rehype-stringify";
import rehypeReact from "rehype-react";

interface Props {
  doc: string;
  mode: ViewMode;
}

const schema = {
  ...defaultSchema,
  attributes: {
    ...defaultSchema.attributes,
    code: [...(defaultSchema.attributes?.code || []), "className"],
  },
};

const Preview = (props: Props) => {
  const { doc, mode } = props;

  if (mode !== ViewMode.Edit) {
    const md = unified()
      .use(remarkParse)
      .use(remarkGfm)
      // .use(remarkRehype)
      // .use(rehypeDocument)
      // .use(rehypeFormat)
      // .use(rehypeStringify)
      .use(remarkReact, {
        createElement: createElement,
        sanitize: schema,
        remarkReactComponents: {
          code: RemarkCode,
        },
      } as any)
      // .use(rehypeReact, {
      //   createElement: createElement,
      //   sanitize: schema,
      //   remarkReactComponents: {
      //     code: RemarkCode,
      //   },
      // } as any)
      .processSync(doc).result;

    return (
      <PreviewWindow $mode={mode} className="markdown-body editor">
        {" "}
        {md as any}
      </PreviewWindow>
    );
  }
};

export default Preview;

import { MutableRefObject, useEffect, useRef, useState } from "react";
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
import { EditorState } from "@codemirror/state";
import { EditorView, keymap, highlightActiveLine, lineNumbers, highlightActiveLineGutter, drawSelection } from "@codemirror/view";
import { syntaxHighlighting, HighlightStyle, indentOnInput, bracketMatching } from "@codemirror/language";
import { tags } from "@lezer/highlight";
import { markdown, markdownLanguage } from "@codemirror/lang-markdown";
import { languages } from "@codemirror/language-data";
import { oneDark } from "@codemirror/theme-one-dark";
import { vim, Vim } from "@replit/codemirror-vim";

interface Props {
  initialDoc: string,
  onChange?: (state: EditorState) => void
}

const transparentTheme = EditorView.theme({
  "&": {
    backgroundColor: "transparent !important",
    height: "100%"
  }
});

const syntaxHighlightingCustom = HighlightStyle.define([
  {
    tag: tags.heading1,
    fontSize: "1.6em",
    fontWeight: "bold"
  },
  {
    tag: tags.heading2,
    fontSize: "1.4em",
    fontWeight: "bold"
  },
  {
    tag: tags.heading3,
    fontSize: "1.2em",
    fontWeight: "bold"
  }
]);

const useCodeMirror = <T extends Element>(
  props: Props
): [MutableRefObject<T | null>, EditorView?] => {
  const refContainer = useRef<T>(null);
  const [editorView, setEditorView] = useState<EditorView>();
  const { onChange } = props;
  useEffect(() => {
    if (!refContainer.current) return;

    const startState = EditorState.create({
      doc: props.initialDoc,
      extensions: [
        vim(),
        keymap.of([...defaultKeymap, ...historyKeymap]),
        lineNumbers(),
        highlightActiveLineGutter(),
        history(),
        indentOnInput(),
        bracketMatching(),
        highlightActiveLine(),
        drawSelection(),
        markdown({
          base: markdownLanguage,
          codeLanguages: languages,
          addKeymap: true
        }),
        oneDark,
        transparentTheme,
        syntaxHighlighting(syntaxHighlightingCustom),
        EditorView.lineWrapping,
        EditorView.updateListener.of(update => {
          if (update.changes) {
            onChange && onChange(update.state);
          }
        })
      ]
    });

    Vim.map(":", "<Esc>");

    const view = new EditorView({
      state: startState,
      parent: refContainer.current
    });

    setEditorView(view);

    return () => {
      view.destroy();
    }
  }, [refContainer]);

  return [refContainer, editorView];
}

export default useCodeMirror;
import { EditorState } from "@codemirror/state";
import { useCallback } from "react";
import useCodeMirror from "./useCodeMirror";
import { EditorWindow } from "./style";
import { ViewMode } from "../types";

interface Props {
  initialDoc: string,
  mode: ViewMode
  onChange: (doc: string) => void
}

const Editor = (props: Props) => {
  const { onChange, initialDoc, mode } = props;

  if (mode !== ViewMode.Preview) {
    const handleChange = useCallback(
      (state: EditorState) => onChange(state.doc.toString()),
      [onChange]
    );
    const [refContainer, editorView] = useCodeMirror<HTMLDivElement>({
      initialDoc,
      onChange: handleChange
    });

    return <EditorWindow $mode={mode} ref={refContainer}></EditorWindow>
  }
}

export default Editor;
HTML ReactJS Markdown 预览 备注JS

评论

0赞 mb21 11/16/2023
也许你应该在你输入的 Markdown 字符串中检查它们?喜欢- [x] foo
0赞 dsadsadsadas dsadasdasda 11/16/2023
@mb21我的意思是我想添加“功能”,以便用户可以像黑曜石一样以 md 格式或 otput html 格式选中复选框
0赞 mb21 11/16/2023
好吧,到目前为止你尝试了什么?问题到底是什么?你能提供一个没有不必要的代码的 stackoverflow.com/help/minimal-reproducible-example 吗?
0赞 dsadsadsadas dsadasdasda 11/17/2023
您可以从此视频中复制代码:youtube.com/...我尝试使用 Rehype 库,您可以看到带注释的代码行
0赞 mb21 11/18/2023
哈哈,你需要把信息放在问题中,而不是视频......投票关闭“需要细节或清晰度”

答: 暂无答案