df5373adbc
列表页改进: - 显示元数据标题而非文件名 - 显示作者、发布时间、平台 - 显示正文概述前两行 - 根据平台显示图标 文章页改进: - 过滤 YAML front matter - 只显示正文内容
132 lines
3.7 KiB
PHP
132 lines
3.7 KiB
PHP
<?php
|
|
require_once 'config.php';
|
|
checkLogin();
|
|
|
|
$user = getCurrentUser();
|
|
$username = $user['username'];
|
|
$docDir = getUserDocDir($username);
|
|
|
|
// 获取文件名
|
|
$file = $_GET['file'] ?? '';
|
|
$search = $_GET['q'] ?? '';
|
|
|
|
// 安全检查
|
|
if (empty($file) || strpos($file, '..') !== false) {
|
|
die('无效的文件名');
|
|
}
|
|
|
|
$filePath = $docDir . '/' . $file;
|
|
|
|
$realPath = realpath($filePath);
|
|
$realDocDir = realpath($docDir);
|
|
if ($realPath === false || strpos($realPath, $realDocDir) !== 0) {
|
|
die('文件不存在或无权访问');
|
|
}
|
|
|
|
if (!file_exists($filePath)) {
|
|
die('文件不存在');
|
|
}
|
|
|
|
$content = file_get_contents($filePath);
|
|
|
|
// 解析元数据
|
|
$title = basename($file);
|
|
$meta = [
|
|
'title' => $title,
|
|
'author' => '',
|
|
'date' => '',
|
|
'platform' => ''
|
|
];
|
|
|
|
// 提取并移除 YAML front matter
|
|
if (preg_match('/^---\s*\n(.*?)\n---\s*\n(.*)$/s', $content, $matches)) {
|
|
$yaml = $matches[1];
|
|
$content = $matches[2];
|
|
|
|
// 解析元数据(用于页面标题)
|
|
if (preg_match('/^title:\s*["\']?(.+?)["\']?\s*$/m', $yaml, $m)) {
|
|
$title = trim($m[1], '"\'');
|
|
$meta['title'] = $title;
|
|
}
|
|
if (preg_match('/^author:\s*(.+?)\s*$/m', $yaml, $m)) {
|
|
$meta['author'] = trim($m[1]);
|
|
}
|
|
if (preg_match('/^date:\s*(.+?)\s*$/m', $yaml, $m)) {
|
|
$meta['date'] = trim($m[1]);
|
|
}
|
|
if (preg_match('/^platform:\s*(.+?)\s*$/m', $yaml, $m)) {
|
|
$meta['platform'] = trim($m[1]);
|
|
}
|
|
}
|
|
|
|
// 简单的 Markdown 转换
|
|
function markdownToHtml($text) {
|
|
// 标题
|
|
$text = preg_replace('/^#### (.*$)/m', '<h4>$1</h4>', $text);
|
|
$text = preg_replace('/^### (.*$)/m', '<h3>$1</h3>', $text);
|
|
$text = preg_replace('/^## (.*$)/m', '<h2>$1</h2>', $text);
|
|
$text = preg_replace('/^# (.*$)/m', '<h1>$1</h1>', $text);
|
|
|
|
// 粗体和斜体
|
|
$text = preg_replace('/\*\*(.+?)\*\*/', '<strong>$1</strong>', $text);
|
|
$text = preg_replace('/\*(.+?)\*/', '<em>$1</em>', $text);
|
|
|
|
// 代码块
|
|
$text = preg_replace('/```(\w*)\n(.*?)```/s', '<pre><code class="language-$1">$2</code></pre>', $text);
|
|
$text = preg_replace('/`(.+?)`/', '<code>$1</code>', $text);
|
|
|
|
// 链接
|
|
$text = preg_replace('/\[(.+?)\]\((.+?)\)/', '<a href="$2" target="_blank">$1</a>', $text);
|
|
|
|
// 列表
|
|
$text = preg_replace('/^- (.*$)/m', '<li>$1</li>', $text);
|
|
$text = preg_replace('/(<li>.*<\/li>\n?)+/', '<ul>$0</ul>', $text);
|
|
|
|
// 段落
|
|
$text = preg_replace('/\n\n/', '</p><p>', $text);
|
|
$text = '<p>' . $text . '</p>';
|
|
|
|
return $text;
|
|
}
|
|
|
|
// 高亮搜索词
|
|
function highlightSearch($text, $search) {
|
|
if (empty($search)) return $text;
|
|
return preg_replace('/(' . preg_quote($search, '/') . ')/i',
|
|
'<mark>$1</mark>', $text);
|
|
}
|
|
|
|
$htmlContent = markdownToHtml(htmlspecialchars($content));
|
|
if ($search) {
|
|
$htmlContent = highlightSearch($htmlContent, $search);
|
|
}
|
|
|
|
$folder = dirname($file) !== '.' ? dirname($file) : '';
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title><?php echo htmlspecialchars($title); ?> - 知识库</title>
|
|
<link rel="stylesheet" href="style.css">
|
|
</head>
|
|
<body>
|
|
<div class="view-page">
|
|
<header class="header">
|
|
<a href="dashboard.php<?php echo $search ? '?q=' . urlencode($search) : ''; ?>" class="btn-back">
|
|
← 返回列表
|
|
</a>
|
|
<h1><?php echo htmlspecialchars($title); ?></h1>
|
|
<?php if ($folder): ?>
|
|
<div class="folder-info">📁 <?php echo htmlspecialchars($folder); ?></div>
|
|
<?php endif; ?>
|
|
</header>
|
|
|
|
<div class="document-content">
|
|
<?php echo $htmlContent; ?>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|