add: home select exp

This commit is contained in:
alivender
2025-05-20 09:35:29 +08:00
parent 8eefed92a8
commit 6d640e8049
27 changed files with 1595 additions and 77 deletions

View File

@@ -1,26 +1,67 @@
<script setup lang="ts">
import { computed } from 'vue';
import { computed, onMounted } from 'vue';
import { marked } from 'marked';
import hljs from 'highlight.js';
// 导入默认样式 - 选择一个适合你的主题
import 'highlight.js/styles/github-dark.css';
const props = defineProps({
content: {
type: String,
required: true
},
removeFirstH1: {
type: Boolean,
default: false
}
});
const renderedContent = computed(() => {
if (!props.content) return '<p>没有内容</p>';
let processedContent = props.content;
// 设置 marked 选项
// 如果需要,移除第一个一级标题
if (props.removeFirstH1) {
const lines = processedContent.split('\n');
const firstH1Index = lines.findIndex(line => line.startsWith('# '));
if (firstH1Index !== -1) {
processedContent = lines.slice(firstH1Index + 1).join('\n');
}
}
// 创建自定义渲染器
const renderer = new marked.Renderer();
marked.setOptions({
// 重写代码块渲染方法,添加语言信息
renderer.code = (code, incomingLanguage) => {
// 确保语言参数是字符串
const language = incomingLanguage || 'plaintext';
// 验证语言
const validLanguage = hljs.getLanguage(language) ? language : 'plaintext';
// 高亮代码
const highlightedCode = hljs.highlight(code, { language: validLanguage }).value;
// 添加语言标签到代码块
return `<pre class="hljs" data-language="${validLanguage}"><code class="language-${validLanguage}">${highlightedCode}</code></pre>`;
};
// 设置 marked 选项
marked.use({
renderer: renderer,
gfm: true,
breaks: true
});
return marked(processedContent);
});
// 页面挂载后,对已渲染的代码块应用高亮效果
onMounted(() => {
// 如果需要在客户端重新高亮(通常不需要,因为我们已经在服务端高亮)
// hljs.highlightAll();
});
</script>
<template>
@@ -33,6 +74,8 @@ const renderedContent = computed(() => {
line-height: 1.6;
padding: 1rem 1.5rem;
max-width: 100%;
background-color: inherit; /* 继承父元素的背景色 */
height: 100%;
}
.markdown-content :deep(img) {
@@ -45,47 +88,64 @@ const renderedContent = computed(() => {
}
.markdown-content :deep(h1) {
margin-top: 2rem;
margin-bottom: 1rem;
margin-top: 2.5rem;
margin-bottom: 1.5rem;
color: hsl(var(--bc));
font-weight: 700;
font-size: 2rem;
font-size: 2.2rem;
line-height: 1.3;
padding-bottom: 0.5rem;
border-bottom: 1px solid hsl(var(--b2));
padding-bottom: 0.7rem;
border-bottom: 2px solid hsl(var(--p) / 0.7);
text-shadow: 1px 1px 2px rgba(0,0,0,0.05);
}
.markdown-content :deep(h2) {
margin-top: 1.8rem;
margin-bottom: 0.8rem;
margin-top: 2rem;
margin-bottom: 1rem;
color: hsl(var(--bc));
font-weight: 600;
font-size: 1.5rem;
font-size: 1.7rem;
line-height: 1.4;
padding-left: 0.5rem;
border-left: 4px solid hsl(var(--p));
padding: 0.5rem 1rem;
border-left: 5px solid hsl(var(--p));
background: linear-gradient(to right, hsl(var(--b2) / 0.5), transparent);
border-radius: 0.3rem;
}
.markdown-content :deep(h3) {
margin-top: 1.5rem;
margin-bottom: 0.75rem;
margin-top: 1.8rem;
margin-bottom: 0.9rem;
color: hsl(var(--bc));
font-weight: 600;
font-size: 1.25rem;
font-size: 1.4rem;
line-height: 1.4;
padding-left: 1rem;
border-left: 3px solid hsl(var(--s));
padding-top: 0.3rem;
padding-bottom: 0.3rem;
}
.markdown-content :deep(h4),
.markdown-content :deep(h5),
.markdown-content :deep(h6) {
margin-top: 1.2rem;
margin-bottom: 0.6rem;
margin-top: 1.5rem;
margin-bottom: 0.7rem;
color: hsl(var(--bc));
font-weight: 600;
font-size: 1.1rem;
font-size: 1.2rem;
line-height: 1.5;
padding-left: 1.5rem;
position: relative;
}
.markdown-content :deep(h4::before),
.markdown-content :deep(h5::before),
.markdown-content :deep(h6::before) {
content: '▶';
color: hsl(var(--p) / 0.7);
position: absolute;
left: 0.2rem;
font-size: 0.9em;
}
.markdown-content :deep(p) {
@@ -97,21 +157,31 @@ const renderedContent = computed(() => {
.markdown-content :deep(ul),
.markdown-content :deep(ol) {
padding-left: 2em;
margin: 0.75rem 0;
padding-left: 2.5em;
margin: 1.25rem 0;
color: hsl(var(--bc) / 0.8);
background-color: hsl(var(--b1) / 0.3);
border-radius: 0.5rem;
padding-top: 0.75rem;
padding-bottom: 0.75rem;
padding-right: 1rem;
border-left: 3px solid hsl(var(--p) / 0.7);
}
.markdown-content :deep(li) {
margin: 0.4rem 0;
margin: 0.5rem 0;
position: relative;
padding-left: 0.5rem;
}
.markdown-content :deep(ul ul),
.markdown-content :deep(ul ol),
.markdown-content :deep(ol ul),
.markdown-content :deep(ol ol) {
margin: 0.4rem 0 0.4rem 1rem;
margin: 0.5rem 0 0.5rem 0.5rem;
padding-left: 1.5rem;
border-left: 2px solid hsl(var(--s) / 0.5);
background-color: transparent;
}
.markdown-content :deep(ul) {
@@ -134,45 +204,142 @@ const renderedContent = computed(() => {
color: hsl(var(--p));
}
.markdown-content :deep(ol li::marker) {
color: hsl(var(--s));
}
/* 代码块样式增强 */
.markdown-content :deep(pre) {
background-color: hsl(var(--b3));
padding: 1rem;
border-radius: 0.5rem;
overflow-x: auto;
border: 1px solid hsl(var(--b2));
margin: 1rem 0;
margin: 1.5rem 0;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
position: relative;
}
.markdown-content :deep(pre::before) {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, hsl(var(--p)), hsl(var(--s)));
border-radius: 0.5rem 0.5rem 0 0;
}
/* 代码语言标签 */
.markdown-content :deep(pre.hljs::after) {
content: attr(class);
content: attr(data-language);
position: absolute;
top: 0;
right: 0;
color: hsl(var(--bc) / 0.7);
font-size: 0.75rem;
background-color: hsl(var(--b2));
padding: 0.2rem 0.5rem;
border-radius: 0 0.3rem 0 0.3rem;
opacity: 0.8;
}
/* 内联代码样式 */
.markdown-content :deep(code) {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
background-color: hsl(var(--b3));
padding: 2px 0.5rem;
background-color: hsl(var(--b3) / 0.7);
padding: 0.2rem 0.5rem;
border-radius: 0.25rem;
font-size: 0.9em;
color: hsl(var(--p));
border: 1px solid hsl(var(--b2) / 0.5);
}
/* 确保代码块内的代码不受内联代码样式影响 */
.markdown-content :deep(pre code) {
background-color: transparent;
padding: 0;
border: none;
color: inherit;
font-size: 0.95em;
line-height: 1.5;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
/* 为常见语言添加一些特殊的高亮效果 */
.markdown-content :deep(.hljs-keyword),
.markdown-content :deep(.hljs-tag),
.markdown-content :deep(.hljs-selector-tag) {
color: #cc99cd; /* 紫色,用于关键字 */
}
.markdown-content :deep(.hljs-string),
.markdown-content :deep(.hljs-regexp),
.markdown-content :deep(.hljs-template-tag) {
color: #7ec699; /* 绿色,用于字符串 */
}
.markdown-content :deep(.hljs-number),
.markdown-content :deep(.hljs-literal) {
color: #f08d49; /* 橙色,用于数字 */
}
.markdown-content :deep(.hljs-comment) {
color: #999999; /* 灰色,用于注释 */
font-style: italic;
}
.markdown-content :deep(.hljs-name),
.markdown-content :deep(.hljs-attribute),
.markdown-content :deep(.hljs-selector-id),
.markdown-content :deep(.hljs-selector-class) {
color: #e2777a; /* 红色用于HTML标签名和属性 */
}
.markdown-content :deep(.hljs-built_in),
.markdown-content :deep(.hljs-builtin-name) {
color: #6196cc; /* 蓝色,用于内置函数 */
}
.markdown-content :deep(.hljs-title),
.markdown-content :deep(.hljs-function) {
color: #f8c555; /* 金色,用于函数名和类名 */
}
.markdown-content :deep(table) {
border-collapse: collapse;
border-collapse: separate;
border-spacing: 0;
width: 100%;
margin: 1rem 0;
margin: 1.5rem 0;
background-color: hsl(var(--b1));
border-radius: 0.5rem;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0,0,0,0.12);
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
border: 1px solid hsl(var(--b2));
}
.markdown-content :deep(th),
.markdown-content :deep(td) {
border: 1px solid hsl(var(--b2));
padding: 0.75rem;
padding: 0.75rem 1rem;
text-align: left;
}
.markdown-content :deep(th) {
background-color: hsl(var(--b2));
font-weight: 500;
background-color: hsl(var(--p) / 0.15);
font-weight: 600;
color: hsl(var(--bc));
border-bottom: 2px solid hsl(var(--p) / 0.5);
}
.markdown-content :deep(tr:nth-child(even)) {
background-color: hsl(var(--b2) / 0.3);
}
.markdown-content :deep(tr:hover) {
background-color: hsl(var(--b2) / 0.5);
}
.markdown-content :deep(td) {
@@ -180,12 +347,29 @@ const renderedContent = computed(() => {
}
.markdown-content :deep(blockquote) {
margin: 1rem 0;
padding: 0.5rem 1rem;
margin: 1.5rem 0;
padding: 1rem 1.5rem;
border-left: 4px solid hsl(var(--p));
background-color: hsl(var(--b2));
color: hsl(var(--bc) / 0.8);
background-color: hsl(var(--b2) / 0.3);
color: hsl(var(--bc) / 0.9);
font-style: italic;
border-radius: 0 0.5rem 0.5rem 0;
box-shadow: 0 2px 5px rgba(0,0,0,0.03);
position: relative;
}
.markdown-content :deep(blockquote::before) {
content: '"';
font-size: 2rem;
color: hsl(var(--p) / 0.3);
position: absolute;
top: 0.5rem;
left: 0.5rem;
font-family: serif;
}
.markdown-content :deep(blockquote p) {
margin-top: 0.5rem;
}
.markdown-content :deep(hr) {
@@ -204,4 +388,16 @@ const renderedContent = computed(() => {
color: hsl(var(--pf));
text-decoration: underline;
}
/* 暗黑模式下的代码高亮调整 */
@media (prefers-color-scheme: dark) {
.markdown-content :deep(pre) {
background-color: hsl(var(--b3));
border-color: hsl(var(--b1) / 0.7);
}
.markdown-content :deep(code) {
background-color: hsl(var(--b2) / 0.7);
}
}
</style>