add: home select exp
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user