From 2a8cb58a82a5a4238fa36520f6fd112d9a3faaaf Mon Sep 17 00:00:00 2001
From: q <787025321@qq.com>
Date: Thu, 7 Aug 2025 15:29:06 +0800
Subject: [PATCH] feat: add copy page functions
---
i18n/en/code.json | 24 ++++
i18n/zh/code.json | 24 ++++
src/components/CopyPageButton/index.tsx | 117 ++++++++++++++++++
.../CopyPageButton/styles.module.scss | 18 +++
src/css/markdown.scss | 1 -
src/theme/DocItem/Content/index.tsx | 48 +++++++
src/theme/DocItem/Content/styles.module.css | 15 +++
.../DocRoot/Layout/Main/styles.module.css | 1 -
static/icons/copied.svg | 1 +
static/icons/copy.svg | 1 +
static/icons/down.svg | 1 +
static/icons/markdown.svg | 1 +
12 files changed, 250 insertions(+), 2 deletions(-)
create mode 100644 src/components/CopyPageButton/index.tsx
create mode 100644 src/components/CopyPageButton/styles.module.scss
create mode 100644 src/theme/DocItem/Content/index.tsx
create mode 100644 src/theme/DocItem/Content/styles.module.css
create mode 100644 static/icons/copied.svg
create mode 100644 static/icons/copy.svg
create mode 100644 static/icons/down.svg
create mode 100644 static/icons/markdown.svg
diff --git a/i18n/en/code.json b/i18n/en/code.json
index de4dd2f009..cbf0cef42d 100644
--- a/i18n/en/code.json
+++ b/i18n/en/code.json
@@ -780,5 +780,29 @@
"Enterprise Features & Licensing": {
"message": "Enterprise Features & Licensing",
"description": "Enterprise Features & Licensing"
+ },
+ "Copy Page": {
+ "message": "Copy Page",
+ "description": "Copy Page"
+ },
+ "Copy page as Markdown for LLMs": {
+ "message": "Copy page as Markdown for LLMs",
+ "description": "Copy page as Markdown for LLMs"
+ },
+ "View as Markdown": {
+ "message": "View as Markdown",
+ "description": "View as Markdown"
+ },
+ "View this page as plain text": {
+ "message": "View this page as plain text",
+ "description": "View this page as plain text"
+ },
+ "Failed to copy markdown": {
+ "message": "Failed to copy markdown",
+ "description": "Failed to copy markdown"
+ },
+ "Copying...": {
+ "message": "Copying...",
+ "description": "Copying..."
}
}
diff --git a/i18n/zh/code.json b/i18n/zh/code.json
index ff69649140..784e0e3318 100644
--- a/i18n/zh/code.json
+++ b/i18n/zh/code.json
@@ -804,5 +804,29 @@
"Enterprise Features & Licensing": {
"message": "企业功能与许可",
"description": "Enterprise Features & Licensing"
+ },
+ "Copy Page": {
+ "message": "复制页面",
+ "description": "Copy Page"
+ },
+ "Copy page as Markdown for LLMs": {
+ "message": "复制为 Markdown 格式,供大语言模型使用",
+ "description": "Copy page as Markdown for LLMs"
+ },
+ "View as Markdown": {
+ "message": "查看 Markdown 格式",
+ "description": "View as Markdown"
+ },
+ "View this page as plain text": {
+ "message": "查看纯文本",
+ "description": "View this page as plain text"
+ },
+ "Failed to copy markdown": {
+ "message": "无法复制 Markdown",
+ "description": "Failed to copy markdown"
+ },
+ "Copying...": {
+ "message": "正在复制...",
+ "description": "Copying..."
}
}
diff --git a/src/components/CopyPageButton/index.tsx b/src/components/CopyPageButton/index.tsx
new file mode 100644
index 0000000000..ef8805d75f
--- /dev/null
+++ b/src/components/CopyPageButton/index.tsx
@@ -0,0 +1,117 @@
+import React, { useState, useMemo, useCallback } from "react";
+import { Button, Dropdown, Flex, Spin } from "antd";
+import styles from "./styles.module.scss";
+import DownArrow from "@site/static/icons/down.svg";
+import MarkdownSvg from "@site/static/icons/markdown.svg";
+import CopySvg from "@site/static/icons/copy.svg";
+import CopiedSvg from "@site/static/icons/copied.svg";
+import { useDoc } from "@docusaurus/plugin-content-docs/client";
+import axios from "axios";
+import $t from "@site/src/utils/tools";
+// mark
+// import TurndownService from "turndown";
+// const turndownService = new TurndownService();
+// const getPageContentAsHtml = (): string | null => {
+// const contentElement = document.querySelector("article");
+// return contentElement ? contentElement.innerHTML : null;
+// };
+
+// const convertHtmlToMarkdown = (html: string): string => {
+// return turndownService.turndown(html);
+// };
+const CopyDropdownButton: React.FC = () => {
+ const [loading, setLoading] = useState(false);
+ const [isCopied, setIsCopied] = useState(false);
+ const { metadata } = useDoc();
+ const sourceUrl = useMemo(() => {
+ return (
+ metadata?.source?.replace(
+ "@site",
+ "https://raw.githubusercontent.com/databendlabs/databend-docs/refs/heads/main"
+ ) || ""
+ );
+ }, [metadata]);
+ const handleCopy = useCallback((url: string) => {
+ if (!url) return;
+ setLoading(true);
+ axios
+ .get(url)
+ .then((response) => {
+ setIsCopied(true);
+ if (response.status === 200) {
+ navigator.clipboard.writeText(response.data);
+ } else {
+ alert($t("Failed to copy markdown"));
+ }
+ })
+ .finally(() => {
+ setLoading(false);
+ setTimeout(() => {
+ setIsCopied(false);
+ }, 3000);
+ });
+ }, []);
+ const menu = useMemo(() => {
+ const items = [
+ {
+ key: "copy",
+ icon: