diff --git a/package.json b/package.json index eb26cfd591..b12d4287f8 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@docusaurus/preset-classic": "^3.8.1", "@docusaurus/theme-mermaid": "^3.8.1", "@mdx-js/react": "^3.0.0", + "@types/turndown": "^5.0.5", "ahooks": "^3.8.0", "antd": "^5.24.8", "axios": "^1.7.2", @@ -54,6 +55,7 @@ "react-scroll-progress-bar": "^2.0.3", "sass": "^1.77.8", "sass-resources-loader": "^2.2.5", + "turndown": "^7.2.0", "vanilla-cookieconsent": "^3.1.0", "xml2js": "^0.6.2" }, diff --git a/src/components/CopyPageButton/index.tsx b/src/components/CopyPageButton/index.tsx index ef8805d75f..4449503cc7 100644 --- a/src/components/CopyPageButton/index.tsx +++ b/src/components/CopyPageButton/index.tsx @@ -8,31 +8,38 @@ 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; -// }; +import TurndownService from "turndown"; +const SPECIAL_LINKS = [ + "/guides/", + "/guides/products/dc/platforms", + "/guides/products/dc/pricing", + "guides/deploy/deploy/non-production/deploying-databend", + "/guides/cloud/new-account", +]; -// const convertHtmlToMarkdown = (html: string): string => { -// return turndownService.turndown(html); -// }; +const getPageContentAsHtml = (): string | null => { + const contentElement = document.querySelector("article"); + return contentElement ? contentElement.innerHTML : null; +}; + +const convertHtmlToMarkdown = (html: string): string => { + const turndownService = new TurndownService(); + 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; + function copyHtml() { + setIsCopied(true); + const htmlContent = getPageContentAsHtml(); + const markdownContent = convertHtmlToMarkdown(htmlContent); + navigator.clipboard.writeText(markdownContent?.replace("Copy Page", "")); + setTimeout(() => { + setIsCopied(false); + }, 3000); + } + function copyMarkdown(url: string) { setLoading(true); axios .get(url) @@ -50,18 +57,35 @@ const CopyDropdownButton: React.FC = () => { setIsCopied(false); }, 3000); }); + } + const sourceUrl = useMemo(() => { + return ( + metadata?.source?.replace( + "@site", + "https://raw.githubusercontent.com/databendlabs/databend-docs/refs/heads/main" + ) || "" + ); + }, [metadata]); + const handleCopy = useCallback((url: string) => { + const nowLink = metadata?.permalink; + if (SPECIAL_LINKS?.some((link) => link === nowLink)) { + copyHtml(); + return; + } + if (!url) return; + copyMarkdown(url); }, []); const menu = useMemo(() => { const items = [ { key: "copy", - icon: , + icon: , label: $t("Copy Page"), description: $t("Copy page as Markdown for LLMs"), }, { key: "markdown", - icon: , + icon: , label: $t("View as Markdown"), description: $t("View this page as plain text"), }, @@ -90,9 +114,9 @@ const CopyDropdownButton: React.FC = () => { {loading ? ( ) : isCopied ? ( - + ) : ( - + )} {loading ? $t("Copying...") : $t("Copy Page")} @@ -105,7 +129,7 @@ const CopyDropdownButton: React.FC = () => { onClick={() => handleCopy(sourceUrl)} menu={menu} placement="bottomRight" - icon={} + icon={} className={styles.buttonCainter} trigger={["click"]} > diff --git a/src/components/CopyPageButton/styles.module.scss b/src/components/CopyPageButton/styles.module.scss index df51154bd6..af17652384 100644 --- a/src/components/CopyPageButton/styles.module.scss +++ b/src/components/CopyPageButton/styles.module.scss @@ -1,5 +1,6 @@ .buttonCainter { max-width: 140px; + max-height: 33px; button { font-weight: 500; border: 1px solid var(--color-border) !important; diff --git a/src/css/custom.scss b/src/css/custom.scss index b7d5589248..4287afb1fe 100644 --- a/src/css/custom.scss +++ b/src/css/custom.scss @@ -368,3 +368,7 @@ textarea { #cc-main .cm { border: 1px solid var(--color-border); } +.ant-space-compact-block { + display: flex; + width: 100%; +} diff --git a/yarn.lock b/yarn.lock index 18dc47a805..0a4ac56411 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3268,6 +3268,11 @@ dependencies: langium "3.3.1" +"@mixmark-io/domino@^2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@mixmark-io/domino/-/domino-2.2.0.tgz#4e8ec69bf1afeb7a14f0628b7e2c0f35bdb336c3" + integrity sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw== + "@module-federation/error-codes@0.16.0": version "0.16.0" resolved "https://registry.yarnpkg.com/@module-federation/error-codes/-/error-codes-0.16.0.tgz#e375b2d10405cf24bae9a798337e4805cbcd69ee" @@ -4381,6 +4386,11 @@ resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== +"@types/turndown@^5.0.5": + version "5.0.5" + resolved "https://registry.npmmirror.com/@types/turndown/-/turndown-5.0.5.tgz#614de24fc9ace4d8c0d9483ba81dc8c1976dd26f" + integrity sha512-TL2IgGgc7B5j78rIccBtlYAnkuv8nUQqhQc+DSYV5j9Be9XOcm/SKOVRuA47xAVI3680Tk9B1d8flK2GWT2+4w== + "@types/unist@*", "@types/unist@^3.0.0": version "3.0.2" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.2.tgz#6dd61e43ef60b34086287f83683a5c1b2dc53d20" @@ -11890,6 +11900,13 @@ tslib@^2.4.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== +turndown@^7.2.0: + version "7.2.0" + resolved "https://registry.npmmirror.com/turndown/-/turndown-7.2.0.tgz#67d614fe8371fb511079a93345abfd156c0ffcf4" + integrity sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A== + dependencies: + "@mixmark-io/domino" "^2.2.0" + type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"