Skip to content

Commit 6540bec

Browse files
h7mlclaude
andcommitted
fix: 编程语言文件生成带语法高亮的预览页面
问题: JavaScript/Python 等代码文件的分享预览显示为纯文本,没有语法高亮 根因: htmlOutput 生成逻辑假设所有非 Markdown 文件都是 HTML,直接存储原始代码 修复方案: - Markdown 类型: 转换为 HTML - HTML 类型: 直接使用内容 - 其他编程语言: 生成包含 highlight.js 的完整 HTML 预览页面 * GitHub Dark 主题样式 * 带文件标题和语言类型的 header * 自动语法高亮和代码格式化 * 响应式布局,支持移动端 影响范围: - POST /api/files (创建文件) - PUT /api/files/[id] (更新文件) 现在分享链接会正确显示带语法高亮的代码预览,而不是纯文本 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 713cbeb commit 6540bec

2 files changed

Lines changed: 78 additions & 3 deletions

File tree

src/app/api/files/[id]/route.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,46 @@ export async function PUT(
174174

175175
const result = await processor.process(content)
176176
htmlOutput = result.toString()
177-
} else {
177+
} else if (file.type === 'html') {
178+
// HTML 类型直接使用内容
178179
htmlOutput = content
180+
} else {
181+
// 其他编程语言类型: 生成带语法高亮的 HTML 预览页面
182+
const { getFileTypeConfig } = await import('@/lib/fileTypes')
183+
const fileConfig = getFileTypeConfig(file.type)
184+
const escapedContent = content
185+
.replace(/&/g, '&amp;')
186+
.replace(/</g, '&lt;')
187+
.replace(/>/g, '&gt;')
188+
.replace(/"/g, '&quot;')
189+
.replace(/'/g, '&#039;')
190+
191+
htmlOutput = `<!DOCTYPE html>
192+
<html lang="zh-CN">
193+
<head>
194+
<meta charset="UTF-8">
195+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
196+
<title>${title || file.title || file.filename} - ${fileConfig.label}</title>
197+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
198+
<style>
199+
body { margin: 0; padding: 20px; background: #0d1117; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; }
200+
.header { color: #c9d1d9; margin-bottom: 20px; }
201+
.header h1 { margin: 0 0 8px 0; font-size: 24px; }
202+
.header .meta { color: #8b949e; font-size: 14px; }
203+
pre { margin: 0; border-radius: 6px; }
204+
code { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 14px; }
205+
</style>
206+
</head>
207+
<body>
208+
<div class="header">
209+
<h1>${title || file.title || file.filename}</h1>
210+
<div class="meta">类型: ${fileConfig.label} | 语言: ${fileConfig.language}</div>
211+
</div>
212+
<pre><code class="language-${fileConfig.language}">${escapedContent}</code></pre>
213+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
214+
<script>hljs.highlightAll();</script>
215+
</body>
216+
</html>`
179217
}
180218
}
181219

src/app/api/files/route.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,46 @@ export async function POST(request: NextRequest) {
6464

6565
const result = await processor.process(content)
6666
htmlOutput = result.toString()
67-
} else {
68-
// 直接使用 HTML 内容
67+
} else if (type === 'html') {
68+
// HTML 类型直接使用内容
6969
htmlOutput = content
70+
} else {
71+
// 其他编程语言类型: 生成带语法高亮的 HTML 预览页面
72+
const { getFileTypeConfig } = await import('@/lib/fileTypes')
73+
const fileConfig = getFileTypeConfig(type)
74+
const escapedContent = content
75+
.replace(/&/g, '&amp;')
76+
.replace(/</g, '&lt;')
77+
.replace(/>/g, '&gt;')
78+
.replace(/"/g, '&quot;')
79+
.replace(/'/g, '&#039;')
80+
81+
htmlOutput = `<!DOCTYPE html>
82+
<html lang="zh-CN">
83+
<head>
84+
<meta charset="UTF-8">
85+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
86+
<title>${title || filename} - ${fileConfig.label}</title>
87+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
88+
<style>
89+
body { margin: 0; padding: 20px; background: #0d1117; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; }
90+
.header { color: #c9d1d9; margin-bottom: 20px; }
91+
.header h1 { margin: 0 0 8px 0; font-size: 24px; }
92+
.header .meta { color: #8b949e; font-size: 14px; }
93+
pre { margin: 0; border-radius: 6px; }
94+
code { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 14px; }
95+
</style>
96+
</head>
97+
<body>
98+
<div class="header">
99+
<h1>${title || filename}</h1>
100+
<div class="meta">类型: ${fileConfig.label} | 语言: ${fileConfig.language}</div>
101+
</div>
102+
<pre><code class="language-${fileConfig.language}">${escapedContent}</code></pre>
103+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
104+
<script>hljs.highlightAll();</script>
105+
</body>
106+
</html>`
70107
}
71108

72109
// 生成文件名和分享链接

0 commit comments

Comments
 (0)