This is an automated email from the ASF dual-hosted git repository.
jeffreyh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git
The following commit(s) were added to refs/heads/master by this push:
new cec304bd920 Generate v4 pdf (#3125)
cec304bd920 is described below
commit cec304bd920f96fb8b11154fdcec7b69c121acb6
Author: yangon <[email protected]>
AuthorDate: Fri Nov 28 16:57:37 2025 +0800
Generate v4 pdf (#3125)
---
scripts/renameFilesAndDirs.js | 98 +++++++++++++++++++++++++++++++++++++++
src/constant/download.data.ts | 7 ++-
src/constant/version.ts | 4 +-
src/theme/TOC/index.tsx | 4 +-
static/pdf/Apache_Doris_v4_x.pdf | Bin 0 -> 60602860 bytes
5 files changed, 108 insertions(+), 5 deletions(-)
diff --git a/scripts/renameFilesAndDirs.js b/scripts/renameFilesAndDirs.js
new file mode 100644
index 00000000000..8e17555ad0e
--- /dev/null
+++ b/scripts/renameFilesAndDirs.js
@@ -0,0 +1,98 @@
+const fs = require('fs');
+const path = require('path');
+
+/**
+ * Replace underscores with hyphens in filenames or directory names.
+ * @param {string} inputPath - relative paths to be processed
+ */
+async function renameFilesAndDirs(inputPath) {
+ const absolutePath = path.resolve(process.cwd(), inputPath);
+
+ if (!fs.existsSync(absolutePath)) {
+ console.error(`❌ Path does not exist: ${absolutePath}`);
+ return;
+ }
+
+ console.log(`🔍 Start processing the path: ${absolutePath}`);
+
+ try {
+ // Process subdirectories and files first, then process the current
directory (depth-first).
+ await processDirectory(absolutePath);
+ console.log('✅ All files and directories have been renamed!');
+ } catch (error) {
+ console.error('❌ error:', error);
+ }
+}
+
+/**
+ * Recursive processing directory
+ */
+async function processDirectory(dirPath) {
+ const items = fs.readdirSync(dirPath);
+
+ for (const item of items) {
+ const fullPath = path.join(dirPath, item);
+ const stats = fs.statSync(fullPath);
+
+ if (stats.isDirectory()) {
+ await processDirectory(fullPath);
+
+ await renameItem(fullPath);
+ } else if (stats.isFile() && isMarkdownFile(item)) {
+ await renameItem(fullPath);
+ }
+ }
+
+ if (dirPath !== path.resolve(process.cwd(), inputPath)) {
+ await renameItem(dirPath);
+ }
+}
+
+/**
+ * Rename a file or directory
+ */
+async function renameItem(oldPath) {
+ const dirName = path.dirname(oldPath);
+ const oldName = path.basename(oldPath);
+
+ if (!oldName.includes('_')) {
+ return;
+ }
+
+ const newName = oldName.replace(/_/g, '-');
+
+ if (oldName === newName) {
+ return;
+ }
+
+ const newPath = path.join(dirName, newName);
+
+ try {
+ if (fs.existsSync(newPath)) {
+ console.log(`⚠️ Skip, target already exists: ${newPath}`);
+ return;
+ }
+
+ fs.renameSync(oldPath, newPath);
+ console.log(`✅ Rename: ${oldName} → ${newName}`);
+
+ } catch (error) {
+ console.error(`❌ Rename failed: ${oldPath} → ${newPath}`,
error.message);
+ }
+}
+
+/**
+ * Check if it is a Markdown file
+ */
+function isMarkdownFile(filename) {
+ return /\.(md|mdx)$/i.test(filename);
+}
+
+const inputPath = process.argv[2];
+
+if (!inputPath) {
+ console.error('❌ Please provide a valid path as an argument.');
+ process.exit(1);
+}
+
+renameFilesAndDirs(inputPath);
\ No newline at end of file
diff --git a/src/constant/download.data.ts b/src/constant/download.data.ts
index 38ca9e4c9a3..7d75acdaea5 100644
--- a/src/constant/download.data.ts
+++ b/src/constant/download.data.ts
@@ -2575,8 +2575,13 @@ export const RUN_ANYWHERE = [
];
export const DOWNLOAD_PDFS = [
+ {
+ version: '4.x',
+ filename: 'Apache Doris 中文手册(v4.x).pdf',
+ link: 'https://doris.apache.org/pdf/Apache_Doris_v4_x.pdf',
+ },
{
- version: '3.0',
+ version: '3.x',
filename: 'Apache Doris 中文手册(v3.0).pdf',
link: 'https://doris.apache.org/pdf/Apache_Doris_v3_0_4412376f6e.pdf',
},
diff --git a/src/constant/version.ts b/src/constant/version.ts
index 048d40f29a3..de901a1f413 100644
--- a/src/constant/version.ts
+++ b/src/constant/version.ts
@@ -1,2 +1,2 @@
-export const VERSIONS = ['1.2', '2.0', '2.1', '3.x', 'dev'];
-export const DEFAULT_VERSION = '3.x';
\ No newline at end of file
+export const VERSIONS = ['1.2', '2.0', '2.1', '3.x', '4.x', 'dev'];
+export const DEFAULT_VERSION = '3.x';
diff --git a/src/theme/TOC/index.tsx b/src/theme/TOC/index.tsx
index 130fa59df45..ad1a38a5041 100644
--- a/src/theme/TOC/index.tsx
+++ b/src/theme/TOC/index.tsx
@@ -55,7 +55,7 @@ export default function TOC({ className, ...props }: Props):
React.ReactElement
}
}
}, [typeof window !== 'undefined' && location.pathname]);
-
+
return (
<div className={clsx(styles.tableOfContents, 'thin-scrollbar',
'toc-container', className)}>
<div style={isBrowser && location.pathname.startsWith('/blog') ? {
display: 'none' } : {}}>
@@ -65,7 +65,7 @@ export default function TOC({ className, ...props }: Props):
React.ReactElement
<span className="group-hover:text-[#444FD9]">{isCN ?
'Doris 首页' : 'Doris Homepage'}</span>
</div>
</Link>
- {isCN && ['3.x', '2.0', '2.1'].includes(currentVersion) ? (
+ {isCN && ['4.x','3.x', '2.0', '2.1'].includes(currentVersion)
? (
<div
className="toc-icon-content group"
onClick={() => {
diff --git a/static/pdf/Apache_Doris_v4_x.pdf b/static/pdf/Apache_Doris_v4_x.pdf
new file mode 100644
index 00000000000..3a6434dfd8e
Binary files /dev/null and b/static/pdf/Apache_Doris_v4_x.pdf differ
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]