-
Notifications
You must be signed in to change notification settings - Fork 0
/
convert.js
145 lines (118 loc) · 4.12 KB
/
convert.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
const fs = require('fs');
const axios = require('axios');
const TurndownService = require('turndown');
const moment = require('moment');
// 檢查並建立 export 資料夾
if (!fs.existsSync('export')) {
fs.mkdirSync('export');
}
// 檢查並建立 export/image 資料夾
if (!fs.existsSync('export/image')) {
fs.mkdirSync('export/image');
}
// 讀取文字檔案
const data = fs.readFileSync('input.txt', 'utf8');
// 使用正則表達式分割文字檔案為不同的文章
const articles = data.split('-----\n');
// 建立 Turndown 服務
const turndownService = new TurndownService();
// 下載圖片並儲存到本地
async function downloadImage(url, folder, filename) {
try {
const response = await axios.get(url, {
responseType: 'arraybuffer',
maxContentLength: 10 * 1024 * 1024 * 50, // 500MB
});
fs.writeFileSync(`export/${folder}/${filename}`, response.data, 'binary');
console.log(`已下載圖片:${filename}`);
} catch (error) {
console.error('無法下載圖片:', error);
}
// 延遲 2 秒後繼續處理下一張圖片
await new Promise(resolve => setTimeout(resolve, 2000));
}
let serialNumber = 1;
let processedCount = 0;
// 遞迴處理 Markdown 檔案
async function processMarkdownFiles(startIndex) {
if (startIndex >= articles.length) {
console.log('所有 Markdown 檔案處理完成!');
return;
}
// 每次處理 1 份檔案
const endIndex = Math.min(startIndex + 1, articles.length);
for (let index = startIndex; index < endIndex; index++) {
const article = articles[index];
// 使用正則表達式匹配所需資訊
const matchTitle = article.match(/TITLE: (.+)\n/);
const matchAuthor = article.match(/AUTHOR: (.+)\n/);
const matchDate = article.match(/DATE: (.+)\n/);
const matchCategory = article.match(/CATEGORY: (.+)\n/);
const matchStatus = article.match(/STATUS: (.+)\n/);
const matchBody = article.match(/BODY:\n([\s\S]+)\n/);
if (
matchTitle &&
matchAuthor &&
matchDate &&
matchCategory &&
matchStatus &&
matchBody
) {
// 取得匹配結果
const title = matchTitle[1];
const author = matchAuthor[1];
const date = moment(matchDate[1], 'MM/DD/YYYY').format('YYYY-MM-DD');
const category = matchCategory[1];
const status = matchStatus[1];
const body = matchBody[1];
// 轉換 HTML 到 Markdown
let markdownBody = turndownService.turndown(body);
// 提取第一個段落作為 description,並移除空格
const description = markdownBody
.split('\n\n')[0]
.replace(/\*/g, '')
.replace(/\s+/g, ' ')
.trim();
// 建立 Markdown 格式
const markdown = `---
lang: zh-Hant-tw
title: ${title}
date: ${date}
category:
- ${category}
description: ${description}
sidebar: false
---
${markdownBody}`;
// 建立資料夾
const folder = `image/${serialNumber}`;
if (!fs.existsSync(`export/${folder}`)) {
fs.mkdirSync(`export/${folder}`, { recursive: true });
}
// 在 Markdown 中處理圖片連結並下載圖片
const markdownWithImages = markdown.replace(/!\[([^\]]+)\]\(([^)]+)\)/g, (match, alt, src) => {
const filename = src.split('/').pop();
// 下載圖片並儲存到本地
downloadImage(src, folder, filename);
// 回傳新的圖片連結格式
return `![${alt}](${folder}/${filename})`;
// 刪除圖片外的連結
}).replace(/\[!\[([^\]]*)\]\(([^)]+)\)\]\([^)]+\)/g, '![$1]($2)');
// 更新 Markdown 內容
fs.writeFileSync(`export/post-${serialNumber}-${date}.md`, markdownWithImages);
console.log(`輸出序號 (${serialNumber}) 為:${serialNumber}`);
serialNumber++;
processedCount++;
} else {
console.error(`無法解析文章 #${index + 1}`);
}
}
console.log(`已處理 ${processedCount} 個 Markdown 檔案`);
// 延遲處理下一批檔案
setTimeout(() => {
processMarkdownFiles(endIndex);
}, 20000); // 延遲 20 秒後處理下一批檔案
}
// 開始處理 Markdown 檔案
processMarkdownFiles(0);
console.log('開始轉換!');