@incremark/react 0.2.7 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -389,6 +389,19 @@ function useIncremark(options = {}) {
389
389
  },
390
390
  [parser, setFootnoteReferenceOrder]
391
391
  );
392
+ const updateOptions = useCallback3(
393
+ (newOptions) => {
394
+ parser.updateOptions(newOptions);
395
+ setCompletedBlocks([]);
396
+ setPendingBlocks([]);
397
+ setMarkdown("");
398
+ setIsLoading(false);
399
+ setIsFinalized(false);
400
+ setFootnoteReferenceOrder([]);
401
+ transformer?.reset();
402
+ },
403
+ [parser, transformer, setFootnoteReferenceOrder]
404
+ );
392
405
  return {
393
406
  /** 已收集的完整 Markdown 字符串 */
394
407
  markdown,
@@ -421,6 +434,8 @@ function useIncremark(options = {}) {
421
434
  reset,
422
435
  /** 一次性渲染(reset + append + finalize) */
423
436
  render,
437
+ /** 更新解析器配置(动态更新,不需要重建实例) */
438
+ updateOptions,
424
439
  /** 解析器实例 */
425
440
  parser,
426
441
  /** 打字机控制 */
@@ -536,8 +551,46 @@ function useBlockTransformer(sourceBlocks, options = {}) {
536
551
  };
537
552
  }
538
553
 
554
+ // src/hooks/useLocale.ts
555
+ import { useContext as useContext2 } from "react";
556
+
557
+ // src/components/ConfigProvider.tsx
558
+ import { createContext as createContext2, useMemo as useMemo3 } from "react";
559
+ import { jsx as jsx2 } from "react/jsx-runtime";
560
+ var LocaleContext = createContext2(null);
561
+ function ConfigProvider({ children, locale = enShared }) {
562
+ const contextValue = useMemo3(() => ({ locale }), [locale]);
563
+ return /* @__PURE__ */ jsx2(LocaleContext.Provider, { value: contextValue, children });
564
+ }
565
+
566
+ // src/hooks/useLocale.ts
567
+ function useLocale() {
568
+ const context = useContext2(LocaleContext);
569
+ if (!context) {
570
+ const t2 = (key) => {
571
+ const keys = key.split(".");
572
+ let value = enShared;
573
+ for (const k of keys) {
574
+ value = value?.[k];
575
+ }
576
+ return value || key;
577
+ };
578
+ return { t: t2 };
579
+ }
580
+ const { locale } = context;
581
+ const t = (key) => {
582
+ const keys = key.split(".");
583
+ let value = locale;
584
+ for (const k of keys) {
585
+ value = value?.[k];
586
+ }
587
+ return value || key;
588
+ };
589
+ return { t };
590
+ }
591
+
539
592
  // src/components/IncremarkInline.tsx
540
- import React3 from "react";
593
+ import React4 from "react";
541
594
  import {
542
595
  hasChunks,
543
596
  getStableText,
@@ -546,7 +599,7 @@ import {
546
599
 
547
600
  // src/components/IncremarkHtmlElement.tsx
548
601
  import React2 from "react";
549
- import { jsx as jsx2 } from "react/jsx-runtime";
602
+ import { jsx as jsx3 } from "react/jsx-runtime";
550
603
  var INLINE_ELEMENTS = [
551
604
  "a",
552
605
  "abbr",
@@ -668,22 +721,22 @@ function toReactProps(attrs) {
668
721
  function renderChildren(children) {
669
722
  if (!children || children.length === 0) return null;
670
723
  if (hasOnlyInlineChildren(children)) {
671
- return /* @__PURE__ */ jsx2(IncremarkInline, { nodes: children });
724
+ return /* @__PURE__ */ jsx3(IncremarkInline, { nodes: children });
672
725
  }
673
726
  return children.map((child, idx) => {
674
727
  if (child.type === "htmlElement") {
675
- return /* @__PURE__ */ jsx2(IncremarkHtmlElement, { node: child }, idx);
728
+ return /* @__PURE__ */ jsx3(IncremarkHtmlElement, { node: child }, idx);
676
729
  }
677
730
  if (child.type === "text") {
678
- return /* @__PURE__ */ jsx2(React2.Fragment, { children: child.value }, idx);
731
+ return /* @__PURE__ */ jsx3(React2.Fragment, { children: child.value }, idx);
679
732
  }
680
733
  if (["strong", "emphasis", "inlineCode", "link", "image", "break"].includes(child.type)) {
681
- return /* @__PURE__ */ jsx2(IncremarkInline, { nodes: [child] }, idx);
734
+ return /* @__PURE__ */ jsx3(IncremarkInline, { nodes: [child] }, idx);
682
735
  }
683
736
  if (child.type === "paragraph") {
684
- return /* @__PURE__ */ jsx2("p", { children: /* @__PURE__ */ jsx2(IncremarkInline, { nodes: child.children }) }, idx);
737
+ return /* @__PURE__ */ jsx3("p", { children: /* @__PURE__ */ jsx3(IncremarkInline, { nodes: child.children }) }, idx);
685
738
  }
686
- return /* @__PURE__ */ jsx2("div", { className: "incremark-unknown-child", children: child.type }, idx);
739
+ return /* @__PURE__ */ jsx3("div", { className: "incremark-unknown-child", children: child.type }, idx);
687
740
  });
688
741
  }
689
742
  var IncremarkHtmlElement = ({ node }) => {
@@ -691,13 +744,78 @@ var IncremarkHtmlElement = ({ node }) => {
691
744
  const Tag = tagName;
692
745
  const reactProps = toReactProps(attrs);
693
746
  if (isVoidElement(tagName)) {
694
- return /* @__PURE__ */ jsx2(Tag, { ...reactProps, className: `incremark-html-element incremark-${tagName} ${reactProps.className || ""}` });
747
+ return /* @__PURE__ */ jsx3(Tag, { ...reactProps, className: `incremark-html-element incremark-${tagName} ${reactProps.className || ""}` });
748
+ }
749
+ return /* @__PURE__ */ jsx3(Tag, { ...reactProps, className: `incremark-html-element incremark-${tagName} ${reactProps.className || ""}`, children: renderChildren(children) });
750
+ };
751
+
752
+ // src/components/IncremarkMath.tsx
753
+ import { useState as useState5, useEffect as useEffect4, useRef as useRef5, useCallback as useCallback5 } from "react";
754
+ import { jsx as jsx4 } from "react/jsx-runtime";
755
+ var IncremarkMath = ({
756
+ node,
757
+ renderDelay = 300
758
+ }) => {
759
+ const [renderedHtml, setRenderedHtml] = useState5("");
760
+ const [isLoading, setIsLoading] = useState5(false);
761
+ const katexRef = useRef5(null);
762
+ const renderTimerRef = useRef5(null);
763
+ const isInline = node.type === "inlineMath";
764
+ const formula = node.value;
765
+ const doRender = useCallback5(async () => {
766
+ if (!formula) return;
767
+ try {
768
+ if (!katexRef.current) {
769
+ const katexModule = await import("katex");
770
+ katexRef.current = katexModule.default;
771
+ }
772
+ const katex = katexRef.current;
773
+ const html = katex.renderToString(formula, {
774
+ displayMode: !isInline,
775
+ throwOnError: false,
776
+ strict: false
777
+ });
778
+ setRenderedHtml(html);
779
+ } catch {
780
+ setRenderedHtml("");
781
+ } finally {
782
+ setIsLoading(false);
783
+ }
784
+ }, [formula, isInline]);
785
+ const scheduleRender = useCallback5(() => {
786
+ if (!formula) {
787
+ setRenderedHtml("");
788
+ return;
789
+ }
790
+ if (renderTimerRef.current) {
791
+ clearTimeout(renderTimerRef.current);
792
+ }
793
+ setIsLoading(true);
794
+ renderTimerRef.current = setTimeout(() => {
795
+ doRender();
796
+ }, renderDelay);
797
+ }, [formula, renderDelay, doRender]);
798
+ useEffect4(() => {
799
+ scheduleRender();
800
+ }, [scheduleRender]);
801
+ useEffect4(() => {
802
+ return () => {
803
+ if (renderTimerRef.current) {
804
+ clearTimeout(renderTimerRef.current);
805
+ }
806
+ };
807
+ }, []);
808
+ if (isInline) {
809
+ return /* @__PURE__ */ jsx4("span", { className: "incremark-math-inline", children: renderedHtml && !isLoading ? /* @__PURE__ */ jsx4("span", { dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ jsx4("code", { className: "math-source", children: formula }) });
695
810
  }
696
- return /* @__PURE__ */ jsx2(Tag, { ...reactProps, className: `incremark-html-element incremark-${tagName} ${reactProps.className || ""}`, children: renderChildren(children) });
811
+ return /* @__PURE__ */ jsx4("div", { className: "incremark-math-block", children: renderedHtml && !isLoading ? /* @__PURE__ */ jsx4("div", { className: "math-rendered", dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ jsx4("pre", { className: "math-source-block", children: /* @__PURE__ */ jsx4("code", { children: formula }) }) });
697
812
  };
698
813
 
699
814
  // src/components/IncremarkInline.tsx
700
- import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
815
+ import { Fragment, jsx as jsx5, jsxs } from "react/jsx-runtime";
816
+ function isInlineMath(node) {
817
+ return node.type === "inlineMath";
818
+ }
701
819
  function isHtmlElementNode(node) {
702
820
  return node.type === "htmlElement";
703
821
  }
@@ -710,45 +828,48 @@ function isLinkReference(node) {
710
828
  var IncremarkInline = ({ nodes }) => {
711
829
  if (!nodes || nodes.length === 0) return null;
712
830
  const { definitions, footnoteDefinitions } = useDefinitions();
713
- return /* @__PURE__ */ jsx3(Fragment, { children: nodes.map((node, i) => {
831
+ return /* @__PURE__ */ jsx5(Fragment, { children: nodes.map((node, i) => {
714
832
  if (node.type === "text") {
715
833
  const textNode = node;
716
834
  if (hasChunks(node) && textNode.chunks && textNode.chunks.length > 0) {
717
- return /* @__PURE__ */ jsxs(React3.Fragment, { children: [
835
+ return /* @__PURE__ */ jsxs(React4.Fragment, { children: [
718
836
  getStableText(textNode),
719
- textNode.chunks.map((chunk) => /* @__PURE__ */ jsx3("span", { "data-chunk-key": chunk.createdAt, className: "incremark-fade-in", children: chunk.text }, chunk.createdAt))
837
+ textNode.chunks.map((chunk) => /* @__PURE__ */ jsx5("span", { "data-chunk-key": chunk.createdAt, className: "incremark-fade-in", children: chunk.text }, chunk.createdAt))
720
838
  ] }, i);
721
839
  }
722
- return /* @__PURE__ */ jsx3(React3.Fragment, { children: node.value }, i);
840
+ return /* @__PURE__ */ jsx5(React4.Fragment, { children: node.value }, i);
841
+ }
842
+ if (isInlineMath(node)) {
843
+ return /* @__PURE__ */ jsx5(IncremarkMath, { node }, i);
723
844
  }
724
845
  if (isHtmlElementNode(node)) {
725
- return /* @__PURE__ */ jsx3(IncremarkHtmlElement, { node }, i);
846
+ return /* @__PURE__ */ jsx5(IncremarkHtmlElement, { node }, i);
726
847
  }
727
848
  if (isHtmlNode(node)) {
728
- return /* @__PURE__ */ jsx3(
849
+ return /* @__PURE__ */ jsx5(
729
850
  "span",
730
851
  {
731
- style: { display: "contents" },
852
+ className: "incremark-inline-html",
732
853
  dangerouslySetInnerHTML: { __html: node.value }
733
854
  },
734
855
  i
735
856
  );
736
857
  }
737
858
  if (node.type === "strong") {
738
- return /* @__PURE__ */ jsx3("strong", { children: /* @__PURE__ */ jsx3(IncremarkInline, { nodes: node.children }) }, i);
859
+ return /* @__PURE__ */ jsx5("strong", { children: /* @__PURE__ */ jsx5(IncremarkInline, { nodes: node.children }) }, i);
739
860
  }
740
861
  if (node.type === "emphasis") {
741
- return /* @__PURE__ */ jsx3("em", { children: /* @__PURE__ */ jsx3(IncremarkInline, { nodes: node.children }) }, i);
862
+ return /* @__PURE__ */ jsx5("em", { children: /* @__PURE__ */ jsx5(IncremarkInline, { nodes: node.children }) }, i);
742
863
  }
743
864
  if (node.type === "inlineCode") {
744
- return /* @__PURE__ */ jsx3("code", { className: "incremark-inline-code", children: node.value }, i);
865
+ return /* @__PURE__ */ jsx5("code", { className: "incremark-inline-code", children: node.value }, i);
745
866
  }
746
867
  if (node.type === "link") {
747
- return /* @__PURE__ */ jsx3("a", { href: node.url, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsx3(IncremarkInline, { nodes: node.children }) }, i);
868
+ return /* @__PURE__ */ jsx5("a", { href: node.url, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsx5(IncremarkInline, { nodes: node.children }) }, i);
748
869
  }
749
870
  if (node.type === "image") {
750
871
  const imageNode = node;
751
- return /* @__PURE__ */ jsx3(
872
+ return /* @__PURE__ */ jsx5(
752
873
  "img",
753
874
  {
754
875
  src: imageNode.url,
@@ -762,7 +883,7 @@ var IncremarkInline = ({ nodes }) => {
762
883
  if (isImageReference(node)) {
763
884
  const definition = definitions[node.identifier];
764
885
  if (definition) {
765
- return /* @__PURE__ */ jsx3(
886
+ return /* @__PURE__ */ jsx5(
766
887
  "img",
767
888
  {
768
889
  src: definition.url,
@@ -784,14 +905,14 @@ var IncremarkInline = ({ nodes }) => {
784
905
  if (isLinkReference(node)) {
785
906
  const definition = definitions[node.identifier];
786
907
  if (definition) {
787
- return /* @__PURE__ */ jsx3(
908
+ return /* @__PURE__ */ jsx5(
788
909
  "a",
789
910
  {
790
911
  href: definition.url,
791
912
  title: definition.title || void 0,
792
913
  target: "_blank",
793
914
  rel: "noopener noreferrer",
794
- children: /* @__PURE__ */ jsx3(IncremarkInline, { nodes: node.children })
915
+ children: /* @__PURE__ */ jsx5(IncremarkInline, { nodes: node.children })
795
916
  },
796
917
  i
797
918
  );
@@ -807,36 +928,175 @@ var IncremarkInline = ({ nodes }) => {
807
928
  if (node.type === "footnoteReference") {
808
929
  const footnoteRef = node;
809
930
  const hasDefinition = footnoteDefinitions[footnoteRef.identifier];
810
- return /* @__PURE__ */ jsx3("sup", { className: "incremark-footnote-ref", children: /* @__PURE__ */ jsx3("a", { href: `#fn-${footnoteRef.identifier}`, id: `fnref-${footnoteRef.identifier}`, children: hasDefinition ? `[${footnoteRef.identifier}]` : `[^${footnoteRef.identifier}]` }) }, i);
931
+ return /* @__PURE__ */ jsx5("sup", { className: "incremark-footnote-ref", children: /* @__PURE__ */ jsx5("a", { href: `#fn-${footnoteRef.identifier}`, id: `fnref-${footnoteRef.identifier}`, children: hasDefinition ? `[${footnoteRef.identifier}]` : `[^${footnoteRef.identifier}]` }) }, i);
811
932
  }
812
933
  if (node.type === "break") {
813
- return /* @__PURE__ */ jsx3("br", {}, i);
934
+ return /* @__PURE__ */ jsx5("br", {}, i);
814
935
  }
815
936
  if (node.type === "delete") {
816
- return /* @__PURE__ */ jsx3("del", { children: /* @__PURE__ */ jsx3(IncremarkInline, { nodes: node.children }) }, i);
937
+ return /* @__PURE__ */ jsx5("del", { children: /* @__PURE__ */ jsx5(IncremarkInline, { nodes: node.children }) }, i);
817
938
  }
818
- return /* @__PURE__ */ jsx3("span", { children: node.value || "" }, i);
939
+ return /* @__PURE__ */ jsx5("span", { children: node.value || "" }, i);
819
940
  }) });
820
941
  };
821
942
 
822
943
  // src/components/IncremarkHeading.tsx
823
- import { jsx as jsx4 } from "react/jsx-runtime";
944
+ import { jsx as jsx6 } from "react/jsx-runtime";
824
945
  var IncremarkHeading = ({ node }) => {
825
946
  const Tag = `h${node.depth}`;
826
- return /* @__PURE__ */ jsx4(Tag, { className: `incremark-heading h${node.depth}`, children: /* @__PURE__ */ jsx4(IncremarkInline, { nodes: node.children }) });
947
+ return /* @__PURE__ */ jsx6(Tag, { className: `incremark-heading h${node.depth}`, children: /* @__PURE__ */ jsx6(IncremarkInline, { nodes: node.children }) });
827
948
  };
828
949
 
829
950
  // src/components/IncremarkParagraph.tsx
830
- import { jsx as jsx5 } from "react/jsx-runtime";
951
+ import { jsx as jsx7 } from "react/jsx-runtime";
831
952
  var IncremarkParagraph = ({ node }) => {
832
- return /* @__PURE__ */ jsx5("p", { className: "incremark-paragraph", children: /* @__PURE__ */ jsx5(IncremarkInline, { nodes: node.children }) });
953
+ return /* @__PURE__ */ jsx7("p", { className: "incremark-paragraph", children: /* @__PURE__ */ jsx7(IncremarkInline, { nodes: node.children }) });
833
954
  };
834
955
 
835
956
  // src/components/IncremarkCode.tsx
836
- import React5, { useState as useState5, useEffect as useEffect4, useRef as useRef5, useCallback as useCallback5 } from "react";
957
+ import React8 from "react";
958
+
959
+ // src/components/IncremarkCodeMermaid.tsx
960
+ import { useState as useState6, useEffect as useEffect5, useRef as useRef6, useCallback as useCallback6 } from "react";
961
+ import { GravityMermaid, LucideCode, LucideEye, LucideCopy, LucideCopyCheck } from "@incremark/icons";
962
+ import { isClipboardAvailable } from "@incremark/shared";
963
+
964
+ // src/components/SvgIcon.tsx
965
+ import { jsx as jsx8 } from "react/jsx-runtime";
966
+ var SvgIcon = ({
967
+ svg,
968
+ sizeClass,
969
+ className
970
+ }) => {
971
+ return /* @__PURE__ */ jsx8(
972
+ "span",
973
+ {
974
+ className: `incremark-icon ${sizeClass || ""} ${className || ""}`.trim(),
975
+ dangerouslySetInnerHTML: { __html: svg },
976
+ "aria-hidden": "true"
977
+ }
978
+ );
979
+ };
980
+
981
+ // src/components/IncremarkCodeMermaid.tsx
982
+ import { jsx as jsx9, jsxs as jsxs2 } from "react/jsx-runtime";
983
+ var IncremarkCodeMermaid = ({
984
+ node,
985
+ mermaidDelay = 500
986
+ }) => {
987
+ const [copied, setCopied] = useState6(false);
988
+ const { t } = useLocale();
989
+ const [mermaidSvg, setMermaidSvg] = useState6("");
990
+ const [mermaidLoading, setMermaidLoading] = useState6(false);
991
+ const [mermaidViewMode, setMermaidViewMode] = useState6("preview");
992
+ const mermaidRef = useRef6(null);
993
+ const mermaidTimerRef = useRef6(null);
994
+ const copyTimeoutRef = useRef6(null);
995
+ const code = node.value;
996
+ const toggleMermaidView = useCallback6(() => {
997
+ setMermaidViewMode((prev) => prev === "preview" ? "source" : "preview");
998
+ }, []);
999
+ const copyCode = useCallback6(async () => {
1000
+ if (!isClipboardAvailable()) return;
1001
+ try {
1002
+ await navigator.clipboard.writeText(code);
1003
+ setCopied(true);
1004
+ if (copyTimeoutRef.current) {
1005
+ clearTimeout(copyTimeoutRef.current);
1006
+ }
1007
+ copyTimeoutRef.current = setTimeout(() => setCopied(false), 2e3);
1008
+ } catch {
1009
+ }
1010
+ }, [code]);
1011
+ const doRenderMermaid = useCallback6(async () => {
1012
+ if (!code) return;
1013
+ try {
1014
+ if (!mermaidRef.current) {
1015
+ const mermaidModule = await import("mermaid");
1016
+ mermaidRef.current = mermaidModule.default;
1017
+ mermaidRef.current.initialize({
1018
+ startOnLoad: false,
1019
+ theme: "dark",
1020
+ securityLevel: "loose",
1021
+ suppressErrorRendering: true
1022
+ });
1023
+ }
1024
+ const mermaid = mermaidRef.current;
1025
+ const id = `mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}`;
1026
+ const { svg } = await mermaid.render(id, code);
1027
+ setMermaidSvg(svg);
1028
+ } catch {
1029
+ setMermaidSvg("");
1030
+ } finally {
1031
+ setMermaidLoading(false);
1032
+ }
1033
+ }, [code]);
1034
+ const scheduleRenderMermaid = useCallback6(() => {
1035
+ if (!code) return;
1036
+ if (mermaidTimerRef.current) {
1037
+ clearTimeout(mermaidTimerRef.current);
1038
+ }
1039
+ setMermaidLoading(true);
1040
+ mermaidTimerRef.current = setTimeout(() => {
1041
+ doRenderMermaid();
1042
+ }, mermaidDelay);
1043
+ }, [code, mermaidDelay, doRenderMermaid]);
1044
+ useEffect5(() => {
1045
+ scheduleRenderMermaid();
1046
+ }, [scheduleRenderMermaid]);
1047
+ useEffect5(() => {
1048
+ return () => {
1049
+ if (mermaidTimerRef.current) {
1050
+ clearTimeout(mermaidTimerRef.current);
1051
+ }
1052
+ if (copyTimeoutRef.current) {
1053
+ clearTimeout(copyTimeoutRef.current);
1054
+ }
1055
+ };
1056
+ }, []);
1057
+ return /* @__PURE__ */ jsxs2("div", { className: "incremark-mermaid", children: [
1058
+ /* @__PURE__ */ jsxs2("div", { className: "mermaid-header", children: [
1059
+ /* @__PURE__ */ jsxs2("span", { className: "language", children: [
1060
+ /* @__PURE__ */ jsx9(SvgIcon, { svg: GravityMermaid, className: "language-icon" }),
1061
+ "MERMAID"
1062
+ ] }),
1063
+ /* @__PURE__ */ jsxs2("div", { className: "mermaid-actions", children: [
1064
+ /* @__PURE__ */ jsx9(
1065
+ "button",
1066
+ {
1067
+ className: "code-btn",
1068
+ onClick: toggleMermaidView,
1069
+ type: "button",
1070
+ disabled: !mermaidSvg,
1071
+ "aria-label": mermaidViewMode === "preview" ? t("mermaid.viewSource") : t("mermaid.preview"),
1072
+ title: mermaidViewMode === "preview" ? "View Source" : "Preview",
1073
+ children: /* @__PURE__ */ jsx9(SvgIcon, { svg: mermaidViewMode === "preview" ? LucideCode : LucideEye })
1074
+ }
1075
+ ),
1076
+ /* @__PURE__ */ jsx9(
1077
+ "button",
1078
+ {
1079
+ className: "code-btn",
1080
+ onClick: copyCode,
1081
+ type: "button",
1082
+ "aria-label": copied ? t("mermaid.copied") : t("mermaid.copy"),
1083
+ title: copied ? "Copied!" : "Copy",
1084
+ children: /* @__PURE__ */ jsx9(SvgIcon, { svg: copied ? LucideCopyCheck : LucideCopy })
1085
+ }
1086
+ )
1087
+ ] })
1088
+ ] }),
1089
+ /* @__PURE__ */ jsx9("div", { className: "mermaid-content", children: mermaidLoading && !mermaidSvg ? /* @__PURE__ */ jsx9("div", { className: "mermaid-loading", children: /* @__PURE__ */ jsx9("pre", { className: "mermaid-source-code", children: code }) }) : mermaidViewMode === "source" ? /* @__PURE__ */ jsx9("pre", { className: "mermaid-source-code", children: code }) : mermaidSvg ? /* @__PURE__ */ jsx9("div", { className: "mermaid-svg", dangerouslySetInnerHTML: { __html: mermaidSvg } }) : /* @__PURE__ */ jsx9("pre", { className: "mermaid-source-code", children: code }) })
1090
+ ] });
1091
+ };
1092
+
1093
+ // src/components/IncremarkCodeDefault.tsx
1094
+ import { useState as useState7, useEffect as useEffect6, useCallback as useCallback7, useRef as useRef7 } from "react";
1095
+ import { LucideCopy as LucideCopy2, LucideCopyCheck as LucideCopyCheck2 } from "@incremark/icons";
1096
+ import { isClipboardAvailable as isClipboardAvailable2 } from "@incremark/shared";
837
1097
 
838
1098
  // src/hooks/useShiki.ts
839
- import React4 from "react";
1099
+ import React6 from "react";
840
1100
  var ShikiManager = class _ShikiManager {
841
1101
  static instance = null;
842
1102
  /** 存储 highlighter 实例,key 为主题名称 */
@@ -928,27 +1188,34 @@ var ShikiManager = class _ShikiManager {
928
1188
  this.highlighters.clear();
929
1189
  }
930
1190
  };
931
- var shikiManager = ShikiManager.getInstance();
1191
+ var shikiManagerInstance = null;
1192
+ function getShikiManager() {
1193
+ if (!shikiManagerInstance) {
1194
+ shikiManagerInstance = ShikiManager.getInstance();
1195
+ }
1196
+ return shikiManagerInstance;
1197
+ }
932
1198
  function useShiki(theme) {
933
- const [isHighlighting, setIsHighlighting] = React4.useState(false);
934
- const highlighterInfoRef = React4.useRef(null);
935
- const getHighlighter = React4.useCallback(async () => {
1199
+ const [isHighlighting, setIsHighlighting] = React6.useState(false);
1200
+ const highlighterInfoRef = React6.useRef(null);
1201
+ const getHighlighter = React6.useCallback(async () => {
936
1202
  if (!highlighterInfoRef.current) {
937
- highlighterInfoRef.current = await shikiManager.getHighlighter(theme);
1203
+ highlighterInfoRef.current = await getShikiManager().getHighlighter(theme);
938
1204
  }
939
1205
  return highlighterInfoRef.current;
940
1206
  }, [theme]);
941
- const highlight = React4.useCallback(async (code, lang, fallbackTheme) => {
1207
+ const highlight = React6.useCallback(async (code, lang, fallbackTheme) => {
942
1208
  setIsHighlighting(true);
943
1209
  try {
944
1210
  const info = await getHighlighter();
1211
+ const manager = getShikiManager();
945
1212
  if (!info.loadedLanguages.has(lang) && lang !== "text") {
946
- await shikiManager.loadLanguage(theme, lang);
1213
+ await manager.loadLanguage(theme, lang);
947
1214
  }
948
1215
  if (!info.loadedThemes.has(theme)) {
949
- await shikiManager.loadTheme(theme);
1216
+ await manager.loadTheme(theme);
950
1217
  }
951
- return await shikiManager.codeToHtml(theme, code, lang, fallbackTheme);
1218
+ return await manager.codeToHtml(theme, code, lang, fallbackTheme);
952
1219
  } catch (e) {
953
1220
  throw e;
954
1221
  } finally {
@@ -961,90 +1228,41 @@ function useShiki(theme) {
961
1228
  };
962
1229
  }
963
1230
 
964
- // src/components/IncremarkCode.tsx
965
- import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
966
- var IncremarkCode = ({
1231
+ // src/components/IncremarkCodeDefault.tsx
1232
+ import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
1233
+ var IncremarkCodeDefault = ({
967
1234
  node,
968
1235
  theme = "github-dark",
969
1236
  fallbackTheme = "github-dark",
970
- disableHighlight = false,
971
- mermaidDelay = 500,
972
- customCodeBlocks,
973
- blockStatus = "completed",
974
- codeBlockConfigs
1237
+ disableHighlight = false
975
1238
  }) => {
976
- const [copied, setCopied] = useState5(false);
977
- const [highlightedHtml, setHighlightedHtml] = useState5("");
978
- const [mermaidSvg, setMermaidSvg] = useState5("");
979
- const [mermaidLoading, setMermaidLoading] = useState5(false);
980
- const [mermaidViewMode, setMermaidViewMode] = useState5("preview");
981
- const mermaidRef = useRef5(null);
982
- const mermaidTimerRef = useRef5(null);
1239
+ const [copied, setCopied] = useState7(false);
1240
+ const [highlightedHtml, setHighlightedHtml] = useState7("");
983
1241
  const language = node.lang || "text";
984
1242
  const code = node.value;
985
- const isMermaid = language === "mermaid";
1243
+ const { t } = useLocale();
986
1244
  const { isHighlighting, highlight } = useShiki(theme);
987
- const CustomCodeBlock = React5.useMemo(() => {
988
- const component = customCodeBlocks?.[language];
989
- if (!component) return null;
990
- const config = codeBlockConfigs?.[language];
991
- if (config?.takeOver) {
992
- return component;
993
- }
994
- if (blockStatus !== "completed") {
995
- return null;
996
- }
997
- return component;
998
- }, [customCodeBlocks, language, blockStatus, codeBlockConfigs]);
999
- const toggleMermaidView = useCallback5(() => {
1000
- setMermaidViewMode((prev) => prev === "preview" ? "source" : "preview");
1001
- }, []);
1002
- const copyCode = useCallback5(async () => {
1245
+ const copyTimeoutRef = useRef7(null);
1246
+ const copyCode = useCallback7(async () => {
1247
+ if (!isClipboardAvailable2()) return;
1003
1248
  try {
1004
1249
  await navigator.clipboard.writeText(code);
1005
1250
  setCopied(true);
1006
- setTimeout(() => setCopied(false), 2e3);
1007
- } catch {
1008
- }
1009
- }, [code]);
1010
- const doRenderMermaid = useCallback5(async () => {
1011
- if (!code) return;
1012
- try {
1013
- if (!mermaidRef.current) {
1014
- const mermaidModule = await import("mermaid");
1015
- mermaidRef.current = mermaidModule.default;
1016
- mermaidRef.current.initialize({
1017
- startOnLoad: false,
1018
- theme: "dark",
1019
- securityLevel: "loose",
1020
- suppressErrorRendering: true
1021
- });
1251
+ if (copyTimeoutRef.current) {
1252
+ clearTimeout(copyTimeoutRef.current);
1022
1253
  }
1023
- const mermaid = mermaidRef.current;
1024
- const id = `mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}`;
1025
- const { svg } = await mermaid.render(id, code);
1026
- setMermaidSvg(svg);
1254
+ copyTimeoutRef.current = setTimeout(() => setCopied(false), 2e3);
1027
1255
  } catch {
1028
- setMermaidSvg("");
1029
- } finally {
1030
- setMermaidLoading(false);
1031
1256
  }
1032
1257
  }, [code]);
1033
- const scheduleRenderMermaid = useCallback5(() => {
1034
- if (!isMermaid || !code) return;
1035
- if (mermaidTimerRef.current) {
1036
- clearTimeout(mermaidTimerRef.current);
1037
- }
1038
- setMermaidLoading(true);
1039
- mermaidTimerRef.current = setTimeout(() => {
1040
- doRenderMermaid();
1041
- }, mermaidDelay);
1042
- }, [isMermaid, code, mermaidDelay, doRenderMermaid]);
1043
- const doHighlight = useCallback5(async () => {
1044
- if (isMermaid) {
1045
- scheduleRenderMermaid();
1046
- return;
1047
- }
1258
+ useEffect6(() => {
1259
+ return () => {
1260
+ if (copyTimeoutRef.current) {
1261
+ clearTimeout(copyTimeoutRef.current);
1262
+ }
1263
+ };
1264
+ }, []);
1265
+ const doHighlight = useCallback7(async () => {
1048
1266
  if (!code || disableHighlight) {
1049
1267
  setHighlightedHtml("");
1050
1268
  return;
@@ -1055,20 +1273,60 @@ var IncremarkCode = ({
1055
1273
  } catch {
1056
1274
  setHighlightedHtml("");
1057
1275
  }
1058
- }, [code, language, fallbackTheme, disableHighlight, isMermaid, highlight, scheduleRenderMermaid]);
1059
- useEffect4(() => {
1276
+ }, [code, language, fallbackTheme, disableHighlight, highlight]);
1277
+ useEffect6(() => {
1060
1278
  doHighlight();
1061
1279
  }, [doHighlight]);
1062
- useEffect4(() => {
1063
- return () => {
1064
- if (mermaidTimerRef.current) {
1065
- clearTimeout(mermaidTimerRef.current);
1066
- }
1067
- };
1068
- }, []);
1280
+ return /* @__PURE__ */ jsxs3("div", { className: "incremark-code", children: [
1281
+ /* @__PURE__ */ jsxs3("div", { className: "code-header", children: [
1282
+ /* @__PURE__ */ jsx10("span", { className: "language", children: language }),
1283
+ /* @__PURE__ */ jsx10(
1284
+ "button",
1285
+ {
1286
+ className: "code-btn",
1287
+ onClick: copyCode,
1288
+ type: "button",
1289
+ "aria-label": copied ? t("code.copied") : t("code.copy"),
1290
+ title: copied ? "Copied!" : "Copy",
1291
+ children: /* @__PURE__ */ jsx10(SvgIcon, { svg: copied ? LucideCopyCheck2 : LucideCopy2 })
1292
+ }
1293
+ )
1294
+ ] }),
1295
+ /* @__PURE__ */ jsx10("div", { className: "code-content", children: isHighlighting && !highlightedHtml ? /* @__PURE__ */ jsx10("div", { className: "code-loading", children: /* @__PURE__ */ jsx10("pre", { children: /* @__PURE__ */ jsx10("code", { children: code }) }) }) : highlightedHtml ? /* @__PURE__ */ jsx10("div", { className: "shiki-wrapper", dangerouslySetInnerHTML: { __html: highlightedHtml } }) : /* @__PURE__ */ jsx10("pre", { className: "code-fallback", children: /* @__PURE__ */ jsx10("code", { children: code }) }) })
1296
+ ] });
1297
+ };
1298
+
1299
+ // src/components/IncremarkCode.tsx
1300
+ import { jsx as jsx11 } from "react/jsx-runtime";
1301
+ var IncremarkCode = ({
1302
+ node,
1303
+ theme = "github-dark",
1304
+ fallbackTheme = "github-dark",
1305
+ disableHighlight = false,
1306
+ mermaidDelay = 500,
1307
+ customCodeBlocks,
1308
+ blockStatus = "completed",
1309
+ codeBlockConfigs,
1310
+ defaultCodeComponent: DefaultCodeComponent = IncremarkCodeDefault
1311
+ }) => {
1312
+ const language = node.lang || "text";
1313
+ const code = node.value;
1314
+ const isMermaid = language === "mermaid";
1315
+ const CustomCodeBlock = React8.useMemo(() => {
1316
+ const component = customCodeBlocks?.[language];
1317
+ if (!component) return null;
1318
+ const config = codeBlockConfigs?.[language];
1319
+ if (config?.takeOver) {
1320
+ return component;
1321
+ }
1322
+ if (blockStatus !== "completed") {
1323
+ return null;
1324
+ }
1325
+ return component;
1326
+ }, [customCodeBlocks, language, blockStatus, codeBlockConfigs]);
1069
1327
  if (CustomCodeBlock) {
1070
1328
  const config = codeBlockConfigs?.[language];
1071
- return /* @__PURE__ */ jsx6(
1329
+ return /* @__PURE__ */ jsx11(
1072
1330
  CustomCodeBlock,
1073
1331
  {
1074
1332
  codeStr: code,
@@ -1079,38 +1337,28 @@ var IncremarkCode = ({
1079
1337
  );
1080
1338
  }
1081
1339
  if (isMermaid) {
1082
- return /* @__PURE__ */ jsxs2("div", { className: "incremark-mermaid", children: [
1083
- /* @__PURE__ */ jsxs2("div", { className: "mermaid-header", children: [
1084
- /* @__PURE__ */ jsx6("span", { className: "language", children: "MERMAID" }),
1085
- /* @__PURE__ */ jsxs2("div", { className: "mermaid-actions", children: [
1086
- /* @__PURE__ */ jsx6(
1087
- "button",
1088
- {
1089
- className: "code-btn",
1090
- onClick: toggleMermaidView,
1091
- type: "button",
1092
- disabled: !mermaidSvg,
1093
- children: mermaidViewMode === "preview" ? "\u6E90\u7801" : "\u9884\u89C8"
1094
- }
1095
- ),
1096
- /* @__PURE__ */ jsx6("button", { className: "code-btn", onClick: copyCode, type: "button", children: copied ? "\u2713 \u5DF2\u590D\u5236" : "\u590D\u5236" })
1097
- ] })
1098
- ] }),
1099
- /* @__PURE__ */ jsx6("div", { className: "mermaid-content", children: mermaidLoading && !mermaidSvg ? /* @__PURE__ */ jsx6("div", { className: "mermaid-loading", children: /* @__PURE__ */ jsx6("pre", { className: "mermaid-source-code", children: code }) }) : mermaidViewMode === "source" ? /* @__PURE__ */ jsx6("pre", { className: "mermaid-source-code", children: code }) : mermaidSvg ? /* @__PURE__ */ jsx6("div", { className: "mermaid-svg", dangerouslySetInnerHTML: { __html: mermaidSvg } }) : /* @__PURE__ */ jsx6("pre", { className: "mermaid-source-code", children: code }) })
1100
- ] });
1340
+ return /* @__PURE__ */ jsx11(
1341
+ IncremarkCodeMermaid,
1342
+ {
1343
+ node,
1344
+ mermaidDelay
1345
+ }
1346
+ );
1101
1347
  }
1102
- return /* @__PURE__ */ jsxs2("div", { className: "incremark-code", children: [
1103
- /* @__PURE__ */ jsxs2("div", { className: "code-header", children: [
1104
- /* @__PURE__ */ jsx6("span", { className: "language", children: language }),
1105
- /* @__PURE__ */ jsx6("button", { className: "code-btn", onClick: copyCode, type: "button", children: copied ? "\u2713 \u5DF2\u590D\u5236" : "\u590D\u5236" })
1106
- ] }),
1107
- /* @__PURE__ */ jsx6("div", { className: "code-content", children: isHighlighting && !highlightedHtml ? /* @__PURE__ */ jsx6("div", { className: "code-loading", children: /* @__PURE__ */ jsx6("pre", { children: /* @__PURE__ */ jsx6("code", { children: code }) }) }) : highlightedHtml ? /* @__PURE__ */ jsx6("div", { className: "shiki-wrapper", dangerouslySetInnerHTML: { __html: highlightedHtml } }) : /* @__PURE__ */ jsx6("pre", { className: "code-fallback", children: /* @__PURE__ */ jsx6("code", { children: code }) }) })
1108
- ] });
1348
+ return /* @__PURE__ */ jsx11(
1349
+ DefaultCodeComponent,
1350
+ {
1351
+ node,
1352
+ theme,
1353
+ fallbackTheme,
1354
+ disableHighlight
1355
+ }
1356
+ );
1109
1357
  };
1110
1358
 
1111
1359
  // src/components/IncremarkList.tsx
1112
- import React6 from "react";
1113
- import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
1360
+ import React9 from "react";
1361
+ import { jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
1114
1362
  function getItemInlineContent(item) {
1115
1363
  const firstChild = item.children[0];
1116
1364
  if (firstChild?.type === "paragraph") {
@@ -1129,13 +1377,13 @@ function getItemBlockChildren(item) {
1129
1377
  var IncremarkList = ({ node }) => {
1130
1378
  const Tag = node.ordered ? "ol" : "ul";
1131
1379
  const isTaskList = node.children?.some((item) => item.checked !== null && item.checked !== void 0);
1132
- return /* @__PURE__ */ jsx7(Tag, { className: `incremark-list ${isTaskList ? "task-list" : ""}`, start: node.start || void 0, children: node.children?.map((item, index) => {
1380
+ return /* @__PURE__ */ jsx12(Tag, { className: `incremark-list ${isTaskList ? "task-list" : ""}`, start: node.start || void 0, children: node.children?.map((item, index) => {
1133
1381
  const isTaskItem = item.checked !== null && item.checked !== void 0;
1134
1382
  const inlineContent = getItemInlineContent(item);
1135
1383
  const blockChildren = getItemBlockChildren(item);
1136
1384
  if (isTaskItem) {
1137
- return /* @__PURE__ */ jsx7("li", { className: "incremark-list-item task-item", children: /* @__PURE__ */ jsxs3("label", { className: "task-label", children: [
1138
- /* @__PURE__ */ jsx7(
1385
+ return /* @__PURE__ */ jsx12("li", { className: "incremark-list-item task-item", children: /* @__PURE__ */ jsxs4("label", { className: "task-label", children: [
1386
+ /* @__PURE__ */ jsx12(
1139
1387
  "input",
1140
1388
  {
1141
1389
  type: "checkbox",
@@ -1144,43 +1392,43 @@ var IncremarkList = ({ node }) => {
1144
1392
  className: "checkbox"
1145
1393
  }
1146
1394
  ),
1147
- /* @__PURE__ */ jsx7("span", { className: "task-content", children: /* @__PURE__ */ jsx7(IncremarkInline, { nodes: inlineContent }) })
1395
+ /* @__PURE__ */ jsx12("span", { className: "task-content", children: /* @__PURE__ */ jsx12(IncremarkInline, { nodes: inlineContent }) })
1148
1396
  ] }) }, index);
1149
1397
  }
1150
- return /* @__PURE__ */ jsxs3("li", { className: "incremark-list-item", children: [
1151
- /* @__PURE__ */ jsx7(IncremarkInline, { nodes: inlineContent }),
1152
- blockChildren.map((child, childIndex) => /* @__PURE__ */ jsx7(React6.Fragment, { children: /* @__PURE__ */ jsx7(IncremarkRenderer, { node: child }) }, childIndex))
1398
+ return /* @__PURE__ */ jsxs4("li", { className: "incremark-list-item", children: [
1399
+ /* @__PURE__ */ jsx12(IncremarkInline, { nodes: inlineContent }),
1400
+ blockChildren.map((child, childIndex) => /* @__PURE__ */ jsx12(React9.Fragment, { children: /* @__PURE__ */ jsx12(IncremarkRenderer, { node: child }) }, childIndex))
1153
1401
  ] }, index);
1154
1402
  }) });
1155
1403
  };
1156
1404
 
1157
1405
  // src/components/IncremarkBlockquote.tsx
1158
- import React7 from "react";
1159
- import { jsx as jsx8 } from "react/jsx-runtime";
1406
+ import React10 from "react";
1407
+ import { jsx as jsx13 } from "react/jsx-runtime";
1160
1408
  var IncremarkBlockquote = ({ node }) => {
1161
- return /* @__PURE__ */ jsx8("blockquote", { className: "incremark-blockquote", children: node.children.map((child, index) => /* @__PURE__ */ jsx8(React7.Fragment, { children: /* @__PURE__ */ jsx8(IncremarkRenderer, { node: child }) }, index)) });
1409
+ return /* @__PURE__ */ jsx13("blockquote", { className: "incremark-blockquote", children: node.children.map((child, index) => /* @__PURE__ */ jsx13(React10.Fragment, { children: /* @__PURE__ */ jsx13(IncremarkRenderer, { node: child }) }, index)) });
1162
1410
  };
1163
1411
 
1164
1412
  // src/components/IncremarkTable.tsx
1165
- import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
1413
+ import { jsx as jsx14, jsxs as jsxs5 } from "react/jsx-runtime";
1166
1414
  function getCellContent(cell) {
1167
1415
  return cell.children;
1168
1416
  }
1169
1417
  var IncremarkTable = ({ node }) => {
1170
- return /* @__PURE__ */ jsx9("div", { className: "incremark-table-wrapper", children: /* @__PURE__ */ jsxs4("table", { className: "incremark-table", children: [
1171
- /* @__PURE__ */ jsx9("thead", { children: node.children?.[0] && /* @__PURE__ */ jsx9("tr", { children: node.children[0].children.map((cell, cellIndex) => /* @__PURE__ */ jsx9(
1418
+ return /* @__PURE__ */ jsx14("div", { className: "incremark-table-wrapper", children: /* @__PURE__ */ jsxs5("table", { className: "incremark-table", children: [
1419
+ /* @__PURE__ */ jsx14("thead", { children: node.children?.[0] && /* @__PURE__ */ jsx14("tr", { children: node.children[0].children.map((cell, cellIndex) => /* @__PURE__ */ jsx14(
1172
1420
  "th",
1173
1421
  {
1174
- style: { textAlign: node.align?.[cellIndex] || "left" },
1175
- children: /* @__PURE__ */ jsx9(IncremarkInline, { nodes: getCellContent(cell) })
1422
+ className: `incremark-table-align-${node.align?.[cellIndex] || "left"}`,
1423
+ children: /* @__PURE__ */ jsx14(IncremarkInline, { nodes: getCellContent(cell) })
1176
1424
  },
1177
1425
  cellIndex
1178
1426
  )) }) }),
1179
- /* @__PURE__ */ jsx9("tbody", { children: node.children?.slice(1).map((row, rowIndex) => /* @__PURE__ */ jsx9("tr", { children: row.children.map((cell, cellIndex) => /* @__PURE__ */ jsx9(
1427
+ /* @__PURE__ */ jsx14("tbody", { children: node.children?.slice(1).map((row, rowIndex) => /* @__PURE__ */ jsx14("tr", { children: row.children.map((cell, cellIndex) => /* @__PURE__ */ jsx14(
1180
1428
  "td",
1181
1429
  {
1182
- style: { textAlign: node.align?.[cellIndex] || "left" },
1183
- children: /* @__PURE__ */ jsx9(IncremarkInline, { nodes: getCellContent(cell) })
1430
+ className: `incremark-table-align-${node.align?.[cellIndex] || "left"}`,
1431
+ children: /* @__PURE__ */ jsx14(IncremarkInline, { nodes: getCellContent(cell) })
1184
1432
  },
1185
1433
  cellIndex
1186
1434
  )) }, rowIndex)) })
@@ -1188,75 +1436,13 @@ var IncremarkTable = ({ node }) => {
1188
1436
  };
1189
1437
 
1190
1438
  // src/components/IncremarkThematicBreak.tsx
1191
- import { jsx as jsx10 } from "react/jsx-runtime";
1439
+ import { jsx as jsx15 } from "react/jsx-runtime";
1192
1440
  var IncremarkThematicBreak = () => {
1193
- return /* @__PURE__ */ jsx10("hr", { className: "incremark-hr" });
1194
- };
1195
-
1196
- // src/components/IncremarkMath.tsx
1197
- import { useState as useState6, useEffect as useEffect5, useRef as useRef6, useCallback as useCallback6 } from "react";
1198
- import { jsx as jsx11 } from "react/jsx-runtime";
1199
- var IncremarkMath = ({
1200
- node,
1201
- renderDelay = 300
1202
- }) => {
1203
- const [renderedHtml, setRenderedHtml] = useState6("");
1204
- const [isLoading, setIsLoading] = useState6(false);
1205
- const katexRef = useRef6(null);
1206
- const renderTimerRef = useRef6(null);
1207
- const isInline = node.type === "inlineMath";
1208
- const formula = node.value;
1209
- const doRender = useCallback6(async () => {
1210
- if (!formula) return;
1211
- try {
1212
- if (!katexRef.current) {
1213
- const katexModule = await import("katex");
1214
- katexRef.current = katexModule.default;
1215
- }
1216
- const katex = katexRef.current;
1217
- const html = katex.renderToString(formula, {
1218
- displayMode: !isInline,
1219
- throwOnError: false,
1220
- strict: false
1221
- });
1222
- setRenderedHtml(html);
1223
- } catch {
1224
- setRenderedHtml("");
1225
- } finally {
1226
- setIsLoading(false);
1227
- }
1228
- }, [formula, isInline]);
1229
- const scheduleRender = useCallback6(() => {
1230
- if (!formula) {
1231
- setRenderedHtml("");
1232
- return;
1233
- }
1234
- if (renderTimerRef.current) {
1235
- clearTimeout(renderTimerRef.current);
1236
- }
1237
- setIsLoading(true);
1238
- renderTimerRef.current = setTimeout(() => {
1239
- doRender();
1240
- }, renderDelay);
1241
- }, [formula, renderDelay, doRender]);
1242
- useEffect5(() => {
1243
- scheduleRender();
1244
- }, [scheduleRender]);
1245
- useEffect5(() => {
1246
- return () => {
1247
- if (renderTimerRef.current) {
1248
- clearTimeout(renderTimerRef.current);
1249
- }
1250
- };
1251
- }, []);
1252
- if (isInline) {
1253
- return /* @__PURE__ */ jsx11("span", { className: "incremark-math-inline", children: renderedHtml && !isLoading ? /* @__PURE__ */ jsx11("span", { dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ jsx11("code", { className: "math-source", children: formula }) });
1254
- }
1255
- return /* @__PURE__ */ jsx11("div", { className: "incremark-math-block", children: renderedHtml && !isLoading ? /* @__PURE__ */ jsx11("div", { className: "math-rendered", dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ jsx11("pre", { className: "math-source-block", children: /* @__PURE__ */ jsx11("code", { children: formula }) }) });
1441
+ return /* @__PURE__ */ jsx15("hr", { className: "incremark-hr" });
1256
1442
  };
1257
1443
 
1258
1444
  // src/components/IncremarkContainer.tsx
1259
- import { jsx as jsx12 } from "react/jsx-runtime";
1445
+ import { jsx as jsx16 } from "react/jsx-runtime";
1260
1446
  function parseOptions(attributes) {
1261
1447
  if (!attributes) return {};
1262
1448
  const options = {};
@@ -1274,22 +1460,22 @@ var IncremarkContainer = ({ node, customContainers }) => {
1274
1460
  const options = parseOptions(node.attributes);
1275
1461
  const CustomContainer = customContainers?.[containerName];
1276
1462
  if (CustomContainer) {
1277
- return /* @__PURE__ */ jsx12(CustomContainer, { name: containerName, options, children: node.children?.map((child, index) => /* @__PURE__ */ jsx12(IncremarkRenderer, { node: child }, index)) });
1463
+ return /* @__PURE__ */ jsx16(CustomContainer, { name: containerName, options, children: node.children?.map((child, index) => /* @__PURE__ */ jsx16(IncremarkRenderer, { node: child }, index)) });
1278
1464
  }
1279
- return /* @__PURE__ */ jsx12("div", { className: `incremark-container incremark-container-${containerName}`, children: node.children && node.children.length > 0 && /* @__PURE__ */ jsx12("div", { className: "incremark-container-content", children: node.children.map((child, index) => /* @__PURE__ */ jsx12(IncremarkRenderer, { node: child }, index)) }) });
1465
+ return /* @__PURE__ */ jsx16("div", { className: `incremark-container incremark-container-${containerName}`, children: node.children && node.children.length > 0 && /* @__PURE__ */ jsx16("div", { className: "incremark-container-content", children: node.children.map((child, index) => /* @__PURE__ */ jsx16(IncremarkRenderer, { node: child }, index)) }) });
1280
1466
  };
1281
1467
 
1282
1468
  // src/components/IncremarkDefault.tsx
1283
- import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
1469
+ import { jsx as jsx17, jsxs as jsxs6 } from "react/jsx-runtime";
1284
1470
  var IncremarkDefault = ({ node }) => {
1285
- return /* @__PURE__ */ jsxs5("div", { className: "incremark-default", children: [
1286
- /* @__PURE__ */ jsx13("span", { className: "type-badge", children: node.type }),
1287
- /* @__PURE__ */ jsx13("pre", { children: JSON.stringify(node, null, 2) })
1471
+ return /* @__PURE__ */ jsxs6("div", { className: "incremark-default", children: [
1472
+ /* @__PURE__ */ jsx17("span", { className: "type-badge", children: node.type }),
1473
+ /* @__PURE__ */ jsx17("pre", { children: JSON.stringify(node, null, 2) })
1288
1474
  ] });
1289
1475
  };
1290
1476
 
1291
1477
  // src/components/IncremarkRenderer.tsx
1292
- import { jsx as jsx14 } from "react/jsx-runtime";
1478
+ import { jsx as jsx18 } from "react/jsx-runtime";
1293
1479
  var defaultComponents = {
1294
1480
  heading: IncremarkHeading,
1295
1481
  paragraph: IncremarkParagraph,
@@ -1325,10 +1511,10 @@ var IncremarkRenderer = ({
1325
1511
  return null;
1326
1512
  }
1327
1513
  if (isHtmlNode2(node)) {
1328
- return /* @__PURE__ */ jsx14("pre", { className: "incremark-html-code", children: /* @__PURE__ */ jsx14("code", { children: node.value }) });
1514
+ return /* @__PURE__ */ jsx18("pre", { className: "incremark-html-code", children: /* @__PURE__ */ jsx18("code", { children: node.value }) });
1329
1515
  }
1330
1516
  if (isContainerNode(node)) {
1331
- return /* @__PURE__ */ jsx14(
1517
+ return /* @__PURE__ */ jsx18(
1332
1518
  IncremarkContainer,
1333
1519
  {
1334
1520
  node,
@@ -1337,26 +1523,27 @@ var IncremarkRenderer = ({
1337
1523
  );
1338
1524
  }
1339
1525
  if (node.type === "code") {
1340
- return /* @__PURE__ */ jsx14(
1526
+ return /* @__PURE__ */ jsx18(
1341
1527
  IncremarkCode,
1342
1528
  {
1343
1529
  node,
1344
1530
  customCodeBlocks,
1345
1531
  codeBlockConfigs,
1346
- blockStatus
1532
+ blockStatus,
1533
+ defaultCodeComponent: components?.["code"]
1347
1534
  }
1348
1535
  );
1349
1536
  }
1350
1537
  const Component = getComponent(node.type, components);
1351
- return /* @__PURE__ */ jsx14(Component, { node });
1538
+ return /* @__PURE__ */ jsx18(Component, { node });
1352
1539
  };
1353
1540
 
1354
1541
  // src/components/IncremarkFootnotes.tsx
1355
- import React9 from "react";
1356
- import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
1542
+ import React11 from "react";
1543
+ import { jsx as jsx19, jsxs as jsxs7 } from "react/jsx-runtime";
1357
1544
  var IncremarkFootnotes = () => {
1358
1545
  const { footnoteDefinitions, footnoteReferenceOrder } = useDefinitions();
1359
- const orderedFootnotes = React9.useMemo(() => {
1546
+ const orderedFootnotes = React11.useMemo(() => {
1360
1547
  return footnoteReferenceOrder.map((identifier) => ({
1361
1548
  identifier,
1362
1549
  definition: footnoteDefinitions[identifier]
@@ -1365,22 +1552,22 @@ var IncremarkFootnotes = () => {
1365
1552
  if (orderedFootnotes.length === 0) {
1366
1553
  return null;
1367
1554
  }
1368
- return /* @__PURE__ */ jsxs6("section", { className: "incremark-footnotes", children: [
1369
- /* @__PURE__ */ jsx15("hr", { className: "incremark-footnotes-divider" }),
1370
- /* @__PURE__ */ jsx15("ol", { className: "incremark-footnotes-list", children: orderedFootnotes.map((item, index) => /* @__PURE__ */ jsxs6(
1555
+ return /* @__PURE__ */ jsxs7("section", { className: "incremark-footnotes", children: [
1556
+ /* @__PURE__ */ jsx19("hr", { className: "incremark-footnotes-divider" }),
1557
+ /* @__PURE__ */ jsx19("ol", { className: "incremark-footnotes-list", children: orderedFootnotes.map((item, index) => /* @__PURE__ */ jsxs7(
1371
1558
  "li",
1372
1559
  {
1373
1560
  id: `fn-${item.identifier}`,
1374
1561
  className: "incremark-footnote-item",
1375
1562
  children: [
1376
- /* @__PURE__ */ jsxs6("div", { className: "incremark-footnote-content", children: [
1377
- /* @__PURE__ */ jsxs6("span", { className: "incremark-footnote-number", children: [
1563
+ /* @__PURE__ */ jsxs7("div", { className: "incremark-footnote-content", children: [
1564
+ /* @__PURE__ */ jsxs7("span", { className: "incremark-footnote-number", children: [
1378
1565
  index + 1,
1379
1566
  "."
1380
1567
  ] }),
1381
- /* @__PURE__ */ jsx15("div", { className: "incremark-footnote-body", children: item.definition.children.map((child, childIndex) => /* @__PURE__ */ jsx15(IncremarkRenderer, { node: child }, childIndex)) })
1568
+ /* @__PURE__ */ jsx19("div", { className: "incremark-footnote-body", children: item.definition.children.map((child, childIndex) => /* @__PURE__ */ jsx19(IncremarkRenderer, { node: child }, childIndex)) })
1382
1569
  ] }),
1383
- /* @__PURE__ */ jsx15(
1570
+ /* @__PURE__ */ jsx19(
1384
1571
  "a",
1385
1572
  {
1386
1573
  href: `#fnref-${item.identifier}`,
@@ -1397,13 +1584,13 @@ var IncremarkFootnotes = () => {
1397
1584
  };
1398
1585
 
1399
1586
  // src/components/IncremarkContainerProvider.tsx
1400
- import { jsx as jsx16 } from "react/jsx-runtime";
1587
+ import { jsx as jsx20 } from "react/jsx-runtime";
1401
1588
  var IncremarkContainerProvider = ({ children, definitions }) => {
1402
- return /* @__PURE__ */ jsx16(DefinitionsContext.Provider, { value: definitions, children });
1589
+ return /* @__PURE__ */ jsx20(DefinitionsContext.Provider, { value: definitions, children });
1403
1590
  };
1404
1591
 
1405
1592
  // src/components/Incremark.tsx
1406
- import { jsx as jsx17, jsxs as jsxs7 } from "react/jsx-runtime";
1593
+ import { jsx as jsx21, jsxs as jsxs8 } from "react/jsx-runtime";
1407
1594
  var Incremark = (props) => {
1408
1595
  const {
1409
1596
  blocks: propsBlocks,
@@ -1419,7 +1606,7 @@ var Incremark = (props) => {
1419
1606
  } = props;
1420
1607
  if (incremark) {
1421
1608
  const { blocks: blocks2, isDisplayComplete: isDisplayComplete2, _definitionsContextValue } = incremark;
1422
- return /* @__PURE__ */ jsx17(IncremarkContainerProvider, { definitions: _definitionsContextValue, children: /* @__PURE__ */ jsx17(
1609
+ return /* @__PURE__ */ jsx21(IncremarkContainerProvider, { definitions: _definitionsContextValue, children: /* @__PURE__ */ jsx21(
1423
1610
  IncremarkInternal,
1424
1611
  {
1425
1612
  blocks: blocks2,
@@ -1436,7 +1623,7 @@ var Incremark = (props) => {
1436
1623
  }
1437
1624
  const blocks = propsBlocks || [];
1438
1625
  const isDisplayComplete = propsIsDisplayComplete;
1439
- return /* @__PURE__ */ jsx17(
1626
+ return /* @__PURE__ */ jsx21(
1440
1627
  IncremarkInternal,
1441
1628
  {
1442
1629
  blocks,
@@ -1463,7 +1650,7 @@ var IncremarkInternal = ({
1463
1650
  completedClass,
1464
1651
  isDisplayComplete
1465
1652
  }) => {
1466
- return /* @__PURE__ */ jsxs7("div", { className: `incremark ${className}`, children: [
1653
+ return /* @__PURE__ */ jsxs8("div", { className: `incremark ${className}`, children: [
1467
1654
  blocks.map((block) => {
1468
1655
  if (block.node.type === "definition" || block.node.type === "footnoteDefinition") {
1469
1656
  return null;
@@ -1475,7 +1662,7 @@ var IncremarkInternal = ({
1475
1662
  showBlockStatus && "incremark-show-status",
1476
1663
  block.isLastPending && "incremark-last-pending"
1477
1664
  ].filter(Boolean).join(" ");
1478
- return /* @__PURE__ */ jsx17("div", { className: classes, children: /* @__PURE__ */ jsx17(
1665
+ return /* @__PURE__ */ jsx21("div", { className: classes, children: /* @__PURE__ */ jsx21(
1479
1666
  IncremarkRenderer,
1480
1667
  {
1481
1668
  node: block.node,
@@ -1487,13 +1674,13 @@ var IncremarkInternal = ({
1487
1674
  }
1488
1675
  ) }, block.id);
1489
1676
  }),
1490
- isDisplayComplete && /* @__PURE__ */ jsx17(IncremarkFootnotes, {})
1677
+ isDisplayComplete && /* @__PURE__ */ jsx21(IncremarkFootnotes, {})
1491
1678
  ] });
1492
1679
  };
1493
1680
 
1494
1681
  // src/components/IncremarkContent.tsx
1495
- import { useEffect as useEffect6, useRef as useRef7, useMemo as useMemo3, useCallback as useCallback7 } from "react";
1496
- import { jsx as jsx18 } from "react/jsx-runtime";
1682
+ import { useEffect as useEffect7, useRef as useRef8, useMemo as useMemo4, useCallback as useCallback8 } from "react";
1683
+ import { jsx as jsx22 } from "react/jsx-runtime";
1497
1684
  var IncremarkContent = (props) => {
1498
1685
  const {
1499
1686
  stream,
@@ -1507,23 +1694,41 @@ var IncremarkContent = (props) => {
1507
1694
  showBlockStatus,
1508
1695
  pendingClass
1509
1696
  } = props;
1510
- const initialOptionsRef = useRef7({
1697
+ const initialOptionsRef = useRef8({
1511
1698
  gfm: true,
1512
1699
  htmlTree: true,
1513
1700
  containers: true,
1514
1701
  math: true,
1515
1702
  ...incremarkOptions
1516
1703
  });
1517
- const { blocks, append, finalize, render, reset, isDisplayComplete, markdown, typewriter, _definitionsContextValue } = useIncremark(initialOptionsRef.current);
1518
- useEffect6(() => {
1519
- if (incremarkOptions?.typewriter) {
1520
- typewriter.setOptions(incremarkOptions.typewriter);
1704
+ const { blocks, append, finalize, render, reset, updateOptions, isDisplayComplete, markdown, typewriter, _definitionsContextValue } = useIncremark(initialOptionsRef.current);
1705
+ const prevOptionsRef = useRef8(incremarkOptions);
1706
+ useEffect7(() => {
1707
+ const prev = prevOptionsRef.current;
1708
+ const current = incremarkOptions;
1709
+ if (prev === current) return;
1710
+ prevOptionsRef.current = current;
1711
+ const prevMath = typeof prev?.math === "object" ? JSON.stringify(prev.math) : String(prev?.math ?? true);
1712
+ const currentMath = typeof current?.math === "object" ? JSON.stringify(current.math) : String(current?.math ?? true);
1713
+ const prevAstBuilder = prev?.astBuilder?.name ?? "default";
1714
+ const currentAstBuilder = current?.astBuilder?.name ?? "default";
1715
+ if (prevMath !== currentMath || prev?.gfm !== current?.gfm || prev?.htmlTree !== current?.htmlTree || prev?.containers !== current?.containers || prevAstBuilder !== currentAstBuilder) {
1716
+ updateOptions({
1717
+ gfm: current?.gfm ?? true,
1718
+ math: current?.math ?? true,
1719
+ htmlTree: current?.htmlTree ?? true,
1720
+ containers: current?.containers ?? true,
1721
+ astBuilder: current?.astBuilder
1722
+ });
1521
1723
  }
1522
- }, [incremarkOptions?.typewriter, typewriter]);
1523
- const isStreamMode = useMemo3(() => typeof stream === "function", [stream]);
1524
- const prevContentRef = useRef7(void 0);
1525
- const isStreamingRef = useRef7(false);
1526
- const handleStreamInput = useCallback7(async () => {
1724
+ if (current?.typewriter) {
1725
+ typewriter.setOptions(current.typewriter);
1726
+ }
1727
+ }, [incremarkOptions, updateOptions, typewriter]);
1728
+ const isStreamMode = useMemo4(() => typeof stream === "function", [stream]);
1729
+ const prevContentRef = useRef8(void 0);
1730
+ const isStreamingRef = useRef8(false);
1731
+ const handleStreamInput = useCallback8(async () => {
1527
1732
  if (!stream || isStreamingRef.current) return;
1528
1733
  isStreamingRef.current = true;
1529
1734
  try {
@@ -1539,7 +1744,7 @@ var IncremarkContent = (props) => {
1539
1744
  isStreamingRef.current = false;
1540
1745
  }
1541
1746
  }, [stream, append, finalize]);
1542
- const handleContentInput = useCallback7((newContent, oldContent) => {
1747
+ const handleContentInput = useCallback8((newContent, oldContent) => {
1543
1748
  if (!newContent) {
1544
1749
  if (oldContent) {
1545
1750
  reset();
@@ -1553,7 +1758,7 @@ var IncremarkContent = (props) => {
1553
1758
  render(newContent);
1554
1759
  }
1555
1760
  }, [append, render, reset]);
1556
- useEffect6(() => {
1761
+ useEffect7(() => {
1557
1762
  if (isStreamMode) {
1558
1763
  handleStreamInput();
1559
1764
  } else {
@@ -1561,12 +1766,12 @@ var IncremarkContent = (props) => {
1561
1766
  }
1562
1767
  prevContentRef.current = content;
1563
1768
  }, [content, isStreamMode, handleStreamInput, handleContentInput]);
1564
- useEffect6(() => {
1769
+ useEffect7(() => {
1565
1770
  if (isFinished && content === markdown) {
1566
1771
  finalize();
1567
1772
  }
1568
1773
  }, [isFinished, content, markdown, finalize]);
1569
- return /* @__PURE__ */ jsx18(IncremarkContainerProvider, { definitions: _definitionsContextValue, children: /* @__PURE__ */ jsx18(
1774
+ return /* @__PURE__ */ jsx22(IncremarkContainerProvider, { definitions: _definitionsContextValue, children: /* @__PURE__ */ jsx22(
1570
1775
  Incremark,
1571
1776
  {
1572
1777
  blocks,
@@ -1583,14 +1788,14 @@ var IncremarkContent = (props) => {
1583
1788
 
1584
1789
  // src/components/AutoScrollContainer.tsx
1585
1790
  import {
1586
- useRef as useRef8,
1587
- useEffect as useEffect7,
1588
- useCallback as useCallback8,
1589
- useState as useState7,
1791
+ useRef as useRef9,
1792
+ useEffect as useEffect8,
1793
+ useCallback as useCallback9,
1794
+ useState as useState8,
1590
1795
  forwardRef,
1591
1796
  useImperativeHandle
1592
1797
  } from "react";
1593
- import { jsx as jsx19 } from "react/jsx-runtime";
1798
+ import { jsx as jsx23 } from "react/jsx-runtime";
1594
1799
  var AutoScrollContainer = forwardRef(
1595
1800
  ({
1596
1801
  children,
@@ -1600,17 +1805,17 @@ var AutoScrollContainer = forwardRef(
1600
1805
  style,
1601
1806
  className
1602
1807
  }, ref) => {
1603
- const containerRef = useRef8(null);
1604
- const [isUserScrolledUp, setIsUserScrolledUp] = useState7(false);
1605
- const lastScrollTopRef = useRef8(0);
1606
- const lastScrollHeightRef = useRef8(0);
1607
- const isNearBottom = useCallback8(() => {
1808
+ const containerRef = useRef9(null);
1809
+ const [isUserScrolledUp, setIsUserScrolledUp] = useState8(false);
1810
+ const lastScrollTopRef = useRef9(0);
1811
+ const lastScrollHeightRef = useRef9(0);
1812
+ const isNearBottom = useCallback9(() => {
1608
1813
  const container = containerRef.current;
1609
1814
  if (!container) return true;
1610
1815
  const { scrollTop, scrollHeight, clientHeight } = container;
1611
1816
  return scrollHeight - scrollTop - clientHeight <= threshold;
1612
1817
  }, [threshold]);
1613
- const scrollToBottom = useCallback8(
1818
+ const scrollToBottom = useCallback9(
1614
1819
  (force = false) => {
1615
1820
  const container = containerRef.current;
1616
1821
  if (!container) return;
@@ -1622,12 +1827,12 @@ var AutoScrollContainer = forwardRef(
1622
1827
  },
1623
1828
  [isUserScrolledUp, behavior]
1624
1829
  );
1625
- const hasScrollbar = useCallback8(() => {
1830
+ const hasScrollbar = useCallback9(() => {
1626
1831
  const container = containerRef.current;
1627
1832
  if (!container) return false;
1628
1833
  return container.scrollHeight > container.clientHeight;
1629
1834
  }, []);
1630
- const handleScroll = useCallback8(() => {
1835
+ const handleScroll = useCallback9(() => {
1631
1836
  const container = containerRef.current;
1632
1837
  if (!container) return;
1633
1838
  const { scrollTop, scrollHeight, clientHeight } = container;
@@ -1649,14 +1854,14 @@ var AutoScrollContainer = forwardRef(
1649
1854
  lastScrollTopRef.current = scrollTop;
1650
1855
  lastScrollHeightRef.current = scrollHeight;
1651
1856
  }, [isNearBottom]);
1652
- useEffect7(() => {
1857
+ useEffect8(() => {
1653
1858
  const container = containerRef.current;
1654
1859
  if (container) {
1655
1860
  lastScrollTopRef.current = container.scrollTop;
1656
1861
  lastScrollHeightRef.current = container.scrollHeight;
1657
1862
  }
1658
1863
  }, []);
1659
- useEffect7(() => {
1864
+ useEffect8(() => {
1660
1865
  const container = containerRef.current;
1661
1866
  if (!container || !enabled) return;
1662
1867
  const observer = new MutationObserver(() => {
@@ -1688,16 +1893,12 @@ var AutoScrollContainer = forwardRef(
1688
1893
  }),
1689
1894
  [scrollToBottom, isUserScrolledUp]
1690
1895
  );
1691
- return /* @__PURE__ */ jsx19(
1896
+ return /* @__PURE__ */ jsx23(
1692
1897
  "div",
1693
1898
  {
1694
1899
  ref: containerRef,
1695
1900
  className: `auto-scroll-container ${className || ""}`.trim(),
1696
- style: {
1697
- overflowY: "auto",
1698
- height: "100%",
1699
- ...style
1700
- },
1901
+ style,
1701
1902
  onScroll: handleScroll,
1702
1903
  children
1703
1904
  }
@@ -1707,21 +1908,21 @@ var AutoScrollContainer = forwardRef(
1707
1908
  AutoScrollContainer.displayName = "AutoScrollContainer";
1708
1909
 
1709
1910
  // src/ThemeProvider.tsx
1710
- import { useEffect as useEffect8, useRef as useRef9 } from "react";
1911
+ import { useEffect as useEffect9, useRef as useRef10 } from "react";
1711
1912
  import { applyTheme } from "@incremark/theme";
1712
- import { jsx as jsx20 } from "react/jsx-runtime";
1913
+ import { jsx as jsx24 } from "react/jsx-runtime";
1713
1914
  var ThemeProvider = ({
1714
1915
  theme,
1715
1916
  children,
1716
1917
  className = ""
1717
1918
  }) => {
1718
- const containerRef = useRef9(null);
1719
- useEffect8(() => {
1919
+ const containerRef = useRef10(null);
1920
+ useEffect9(() => {
1720
1921
  if (containerRef.current) {
1721
1922
  applyTheme(containerRef.current, theme);
1722
1923
  }
1723
1924
  }, [theme]);
1724
- return /* @__PURE__ */ jsx20("div", { ref: containerRef, className: `incremark-theme-provider ${className}`.trim(), children });
1925
+ return /* @__PURE__ */ jsx24("div", { ref: containerRef, className: `incremark-theme-provider ${className}`.trim(), children });
1725
1926
  };
1726
1927
 
1727
1928
  // src/index.ts
@@ -1747,9 +1948,11 @@ import {
1747
1948
  mergeTheme,
1748
1949
  applyTheme as applyTheme2
1749
1950
  } from "@incremark/theme";
1951
+ import { en as enShared, zhCN as zhCNShared } from "@incremark/shared";
1750
1952
  export {
1751
1953
  AutoScrollContainer,
1752
1954
  BlockTransformer2 as BlockTransformer,
1955
+ ConfigProvider,
1753
1956
  DefinitionsProvider,
1754
1957
  Incremark,
1755
1958
  IncremarkContainerProvider,
@@ -1769,6 +1972,7 @@ export {
1769
1972
  darkTheme,
1770
1973
  defaultPlugins2 as defaultPlugins,
1771
1974
  defaultTheme,
1975
+ enShared as en,
1772
1976
  generateCSSVars,
1773
1977
  imagePlugin,
1774
1978
  mathPlugin,
@@ -1779,7 +1983,9 @@ export {
1779
1983
  useBlockTransformer,
1780
1984
  useDefinitions,
1781
1985
  useDevTools,
1782
- useIncremark
1986
+ useIncremark,
1987
+ useLocale,
1988
+ zhCNShared as zhCN
1783
1989
  };
1784
1990
  /**
1785
1991
  * @file Definitions Context - 管理 Markdown 引用定义