2025-07-10 08:52:41 +08:00
|
|
|
|
<template>
|
|
|
|
|
<view class="markdown-container">
|
|
|
|
|
<mp-html :content="renderedContent" :domain="domain" :lazy-load="true" :scroll-table="true" :selectable="true" />
|
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
2025-07-10 10:48:28 +08:00
|
|
|
|
import { marked } from 'marked';
|
2025-07-10 09:41:17 +08:00
|
|
|
|
import hljs from 'highlight.js';
|
2025-07-10 10:48:28 +08:00
|
|
|
|
import mpHtml from '@/node_modules/mp-html/dist/uni-app/components/mp-html/mp-html.vue';
|
2025-07-10 08:52:41 +08:00
|
|
|
|
|
2025-07-15 09:21:35 +08:00
|
|
|
|
// 自定义渲染器,修改列表的渲染方式
|
|
|
|
|
const renderer = new marked.Renderer();
|
|
|
|
|
|
|
|
|
|
// 重写粗体渲染方法,确保粗体文本不会导致不当换行
|
|
|
|
|
renderer.strong = function(text) {
|
|
|
|
|
// 确保文本周围没有不必要的空格
|
|
|
|
|
const trimmedText = text.trim();
|
|
|
|
|
return `<strong class="custom-strong" style="font-weight:900 !important;display:inline !important;white-space:normal !important;word-break:normal !important;">${trimmedText}</strong>`;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 重写列表项渲染方法 - 使用特殊的包装来确保内容在一行
|
|
|
|
|
renderer.listitem = function(text) {
|
|
|
|
|
return `<li class="custom-list-item"><div class="list-item-wrapper" style="text-align:left !important;letter-spacing:normal !important;word-spacing:normal !important;text-justify:none !important;">${text}</div></li>`;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 重写有序列表渲染方法
|
|
|
|
|
renderer.list = function(body, ordered) {
|
|
|
|
|
const type = ordered ? 'ol' : 'ul';
|
|
|
|
|
const className = ordered ? 'custom-ordered-list' : 'custom-unordered-list';
|
|
|
|
|
return `<${type} class="${className}">${body}</${type}>`;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 重写段落渲染方法,确保换行正确
|
|
|
|
|
renderer.paragraph = function(text) {
|
|
|
|
|
return `<p class="custom-paragraph">${text}</p>`;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 重写链接渲染方法,确保链接文本正常显示
|
|
|
|
|
renderer.link = function(href, title, text) {
|
|
|
|
|
return `<a href="${href}" title="${title || ''}" style="display:inline !important;white-space:normal !important;word-break:break-all !important;letter-spacing:normal !important;word-spacing:normal !important;text-align:left !important;">${text}</a>`;
|
|
|
|
|
};
|
|
|
|
|
|
2025-07-15 14:39:22 +08:00
|
|
|
|
// 重写表格渲染方法,添加表格容器使其可滚动
|
|
|
|
|
renderer.table = function(header, body) {
|
|
|
|
|
return `<div class="table-container"><table class="custom-table">
|
|
|
|
|
<thead>${header}</thead>
|
|
|
|
|
<tbody>${body}</tbody>
|
|
|
|
|
</table></div>`;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 重写表格单元格渲染方法
|
|
|
|
|
renderer.tablecell = function(content, flags) {
|
|
|
|
|
const type = flags.header ? 'th' : 'td';
|
|
|
|
|
const align = flags.align ? ` style="text-align:${flags.align}"` : '';
|
|
|
|
|
return `<${type}${align}>${content}</${type}>`;
|
|
|
|
|
};
|
|
|
|
|
|
2025-07-10 08:52:41 +08:00
|
|
|
|
// 配置marked
|
2025-07-10 10:48:28 +08:00
|
|
|
|
marked.use({
|
2025-07-15 09:21:35 +08:00
|
|
|
|
renderer: renderer,
|
2025-07-10 08:52:41 +08:00
|
|
|
|
highlight: function(code, lang) {
|
|
|
|
|
try {
|
2025-07-10 09:41:17 +08:00
|
|
|
|
return hljs.highlightAuto(code, [lang]).value;
|
2025-07-10 08:52:41 +08:00
|
|
|
|
} catch (e) {
|
2025-07-10 09:41:17 +08:00
|
|
|
|
return hljs.highlightAuto(code).value;
|
2025-07-10 08:52:41 +08:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
gfm: true,
|
|
|
|
|
breaks: true,
|
|
|
|
|
pedantic: false,
|
|
|
|
|
sanitize: false,
|
|
|
|
|
smartLists: true,
|
|
|
|
|
smartypants: false
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: 'MarkdownViewer',
|
2025-07-10 10:48:28 +08:00
|
|
|
|
components: {
|
|
|
|
|
mpHtml
|
|
|
|
|
},
|
2025-07-10 08:52:41 +08:00
|
|
|
|
props: {
|
|
|
|
|
// Markdown原始内容
|
|
|
|
|
content: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: ''
|
|
|
|
|
},
|
|
|
|
|
// 主域名(用于链接拼接)
|
|
|
|
|
domain: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: ''
|
|
|
|
|
},
|
|
|
|
|
// 自定义样式
|
|
|
|
|
customStyle: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: ''
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
// 将Markdown转换为HTML
|
|
|
|
|
renderedContent() {
|
|
|
|
|
if (!this.content) return '';
|
|
|
|
|
try {
|
2025-07-15 09:21:35 +08:00
|
|
|
|
// 添加自定义样式,确保内容自动换行和列表正确显示
|
2025-07-11 15:58:10 +08:00
|
|
|
|
const styleTag = `<style>
|
|
|
|
|
* {
|
2025-07-14 10:27:41 +08:00
|
|
|
|
max-width: 100% !important;
|
2025-07-15 09:21:35 +08:00
|
|
|
|
word-break: normal !important;
|
2025-07-11 15:58:10 +08:00
|
|
|
|
overflow-wrap: break-word !important;
|
2025-07-15 09:21:35 +08:00
|
|
|
|
box-sizing: border-box !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 段落样式修复 */
|
|
|
|
|
.custom-paragraph, p {
|
|
|
|
|
display: block !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
margin: 10rpx 0 !important;
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
line-height: 1.6 !important;
|
|
|
|
|
text-align: left !important; /* 改为左对齐,不要两端对齐 */
|
2025-07-11 15:58:10 +08:00
|
|
|
|
}
|
2025-07-15 09:21:35 +08:00
|
|
|
|
|
|
|
|
|
/* 解决粗体文本和普通文本换行问题 */
|
|
|
|
|
.custom-strong, strong, b {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
font-weight: 900 !important;
|
2025-07-14 10:27:41 +08:00
|
|
|
|
white-space: normal !important;
|
2025-07-15 09:21:35 +08:00
|
|
|
|
word-break: normal !important;
|
|
|
|
|
overflow-wrap: break-word !important;
|
|
|
|
|
vertical-align: baseline !important;
|
|
|
|
|
position: static !important;
|
|
|
|
|
float: none !important;
|
|
|
|
|
margin: 0 !important;
|
|
|
|
|
padding: 0 !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 专门用于列表项内容包装的容器 */
|
|
|
|
|
.list-item-wrapper {
|
|
|
|
|
display: inline-block !important;
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
/* 关键属性:防止内部元素分列 */
|
|
|
|
|
table-layout: fixed !important;
|
|
|
|
|
word-break: normal !important;
|
2025-07-14 10:27:41 +08:00
|
|
|
|
text-align: left !important;
|
2025-07-15 09:21:35 +08:00
|
|
|
|
text-justify: none !important;
|
|
|
|
|
letter-spacing: normal !important;
|
|
|
|
|
word-spacing: normal !important;
|
|
|
|
|
text-align-last: left !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 内联元素修复 */
|
|
|
|
|
span, a, em, strong, .custom-strong, b {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
vertical-align: baseline !important;
|
|
|
|
|
float: none !important;
|
|
|
|
|
position: static !important;
|
|
|
|
|
width: auto !important;
|
|
|
|
|
height: auto !important;
|
|
|
|
|
/* 确保内部不会有奇怪的换行 */
|
|
|
|
|
word-break: keep-all !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 特别针对粗体文本 */
|
|
|
|
|
.custom-strong, strong, b {
|
|
|
|
|
font-weight: bold !important;
|
|
|
|
|
display: inline !important;
|
|
|
|
|
vertical-align: baseline !important;
|
|
|
|
|
position: static !important;
|
|
|
|
|
margin: 0 !important;
|
|
|
|
|
padding: 0 !important;
|
|
|
|
|
border: none !important;
|
|
|
|
|
float: none !important;
|
|
|
|
|
width: auto !important;
|
|
|
|
|
word-break: keep-all !important;
|
|
|
|
|
word-wrap: normal !important;
|
|
|
|
|
line-height: inherit !important;
|
|
|
|
|
color: inherit !important; /* 确保颜色正确继承 */
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 14:39:22 +08:00
|
|
|
|
/* 专门修复mp-html组件生成的列表结构 */
|
|
|
|
|
div[data-v-7e5387f] {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 处理列表编号所在的容器 - 重要修复 */
|
|
|
|
|
div[data-v-7e5387f] {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
white-space: nowrap !important; /* 防止编号和首个字符分开 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 首行缩进优化(确保列表项不会被意外截断) */
|
|
|
|
|
div div {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 09:21:35 +08:00
|
|
|
|
/* 有序列表样式 */
|
|
|
|
|
.custom-ordered-list, ol {
|
|
|
|
|
display: block !important;
|
|
|
|
|
counter-reset: item !important;
|
|
|
|
|
padding-left: 0 !important;
|
|
|
|
|
margin: 10rpx 0 !important;
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
list-style-type: none !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 无序列表样式 */
|
|
|
|
|
.custom-unordered-list, ul {
|
|
|
|
|
display: block !important;
|
|
|
|
|
padding-left: 0 !important;
|
|
|
|
|
margin: 10rpx 0 !important;
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
list-style-type: none !important;
|
2025-07-14 10:27:41 +08:00
|
|
|
|
}
|
2025-07-15 09:21:35 +08:00
|
|
|
|
|
2025-07-15 14:39:22 +08:00
|
|
|
|
/* 针对mp-html生成的列表标记容器 */
|
|
|
|
|
div[style*="undefined"] {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
white-space: nowrap !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 对列表项第一个元素特殊处理 */
|
|
|
|
|
h4 {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
margin: 0 !important;
|
|
|
|
|
padding: 0 !important;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 09:21:35 +08:00
|
|
|
|
/* 列表项共用样式 */
|
|
|
|
|
.custom-list-item, ol li, ul li {
|
|
|
|
|
display: flex !important;
|
|
|
|
|
padding-left: 0 !important;
|
|
|
|
|
margin-bottom: 8rpx !important;
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
position: relative !important;
|
|
|
|
|
/* 确保内容在一行显示 */
|
|
|
|
|
flex-wrap: nowrap !important;
|
|
|
|
|
align-items: flex-start !important; /* 顶部对齐 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 列表项内容样式 */
|
|
|
|
|
.custom-list-item > *:not(ol):not(ul),
|
|
|
|
|
ol li > *:not(ol):not(ul),
|
|
|
|
|
ul li > *:not(ol):not(ul) {
|
|
|
|
|
flex: 1 !important;
|
|
|
|
|
display: inline !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
word-break: normal !important;
|
|
|
|
|
width: auto !important;
|
|
|
|
|
/* 确保文本不会被分列 */
|
|
|
|
|
column-count: 1 !important;
|
|
|
|
|
column-width: auto !important;
|
|
|
|
|
column-span: all !important;
|
|
|
|
|
text-align: left !important; /* 确保文本左对齐 */
|
|
|
|
|
justify-content: flex-start !important; /* 左对齐 */
|
|
|
|
|
text-justify: none !important; /* 禁用两端对齐 */
|
|
|
|
|
letter-spacing: normal !important; /* 正常字间距 */
|
|
|
|
|
word-spacing: normal !important; /* 正常词间距 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 列表项内的p标签特殊处理 */
|
|
|
|
|
ol li p, ul li p, .custom-list-item p {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
margin: 0 !important;
|
|
|
|
|
padding: 0 !important;
|
|
|
|
|
width: auto !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 有序列表项编号 */
|
|
|
|
|
.custom-ordered-list > .custom-list-item {
|
|
|
|
|
counter-increment: item !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.custom-ordered-list > .custom-list-item::before,
|
|
|
|
|
ol > li::before {
|
|
|
|
|
content: counter(item)"." !important;
|
|
|
|
|
min-width: 40rpx !important;
|
|
|
|
|
width: 40rpx !important;
|
|
|
|
|
font-weight: bold !important;
|
|
|
|
|
text-align: right !important;
|
|
|
|
|
margin-right: 8rpx !important;
|
|
|
|
|
padding-right: 0 !important;
|
|
|
|
|
flex-shrink: 0 !important;
|
|
|
|
|
align-self: flex-start !important; /* 顶部对齐 */
|
|
|
|
|
padding-top: 1rpx !important; /* 微调垂直位置 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 无序列表项标记 */
|
|
|
|
|
.custom-unordered-list > .custom-list-item::before,
|
|
|
|
|
ul > li::before {
|
|
|
|
|
content: "-" !important;
|
|
|
|
|
min-width: 40rpx !important;
|
|
|
|
|
width: 40rpx !important;
|
|
|
|
|
font-weight: bold !important;
|
|
|
|
|
text-align: center !important;
|
|
|
|
|
margin-right: 8rpx !important;
|
|
|
|
|
padding-right: 0 !important;
|
|
|
|
|
flex-shrink: 0 !important;
|
|
|
|
|
align-self: flex-start !important; /* 顶部对齐 */
|
|
|
|
|
padding-top: 1rpx !important; /* 微调垂直位置 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 代码块样式 */
|
2025-07-11 15:58:10 +08:00
|
|
|
|
pre, code {
|
|
|
|
|
white-space: pre-wrap !important;
|
|
|
|
|
word-wrap: break-word !important;
|
2025-07-14 10:27:41 +08:00
|
|
|
|
word-break: break-all !important;
|
2025-07-11 15:58:10 +08:00
|
|
|
|
overflow-wrap: break-word !important;
|
|
|
|
|
}
|
2025-07-15 09:21:35 +08:00
|
|
|
|
|
|
|
|
|
/* 禁用可能导致问题的CSS特性 */
|
|
|
|
|
* {
|
|
|
|
|
column-count: 1 !important;
|
|
|
|
|
column-gap: 0 !important;
|
|
|
|
|
column-rule: none !important;
|
|
|
|
|
column-span: all !important;
|
|
|
|
|
column-width: auto !important;
|
|
|
|
|
columns: auto !important;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-11 15:58:10 +08:00
|
|
|
|
${this.customStyle || ''}
|
|
|
|
|
</style>`;
|
2025-07-10 08:52:41 +08:00
|
|
|
|
|
2025-07-15 09:21:35 +08:00
|
|
|
|
// 对Markdown内容进行预处理,修复可能导致问题的模式
|
|
|
|
|
let processedContent = this.content;
|
|
|
|
|
|
|
|
|
|
// 将Markdown内容分解为段落,分别处理每个段落
|
|
|
|
|
const paragraphs = processedContent.split('\n\n');
|
|
|
|
|
const processedParagraphs = paragraphs.map(paragraph => {
|
|
|
|
|
// 处理一个段落内的粗体文本
|
|
|
|
|
return paragraph.replace(/\*\*([^*]+?)\*\*/g, (match, content) => {
|
|
|
|
|
// 返回无缝拼接的HTML粗体标签
|
|
|
|
|
return `<strong style="font-weight:900 !important;display:inline !important;">${content}</strong>`;
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 重新组合处理后的段落
|
|
|
|
|
processedContent = processedParagraphs.join('\n\n');
|
|
|
|
|
|
|
|
|
|
// 使用marked处理剩余的Markdown语法
|
|
|
|
|
let htmlContent = marked(processedContent);
|
|
|
|
|
|
|
|
|
|
// 后处理HTML,确保任何遗漏的粗体标记也能被处理
|
|
|
|
|
htmlContent = htmlContent
|
|
|
|
|
// 处理任何遗漏的**标记
|
|
|
|
|
.replace(/\*\*([^*]+?)\*\*/g, (match, content) => {
|
|
|
|
|
return `<strong style="font-weight:900 !important;display:inline !important;">${content}</strong>`;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 处理HTML,确保所有文本元素都有正确的显示属性
|
|
|
|
|
let processedHtml = htmlContent;
|
|
|
|
|
|
2025-07-15 14:39:22 +08:00
|
|
|
|
// 处理表格,确保表格正确显示
|
|
|
|
|
processedHtml = processedHtml.replace(/<table([^>]*)>/g, (match, attrs) => {
|
|
|
|
|
return `<div class="table-container"><table${attrs || ''} class="custom-table">`;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
processedHtml = processedHtml.replace(/<\/table>/g, '</table></div>');
|
|
|
|
|
|
2025-07-15 09:21:35 +08:00
|
|
|
|
// 将所有段落包装在特殊div中,防止段落间的换行问题
|
|
|
|
|
processedHtml = processedHtml.replace(/<p([^>]*)>(.*?)<\/p>/gs, (match, attrs, content) => {
|
|
|
|
|
// 确保段落内容连续显示,不被换行打断
|
|
|
|
|
return `<p${attrs} style="white-space:normal !important;word-break:normal !important;overflow-wrap:break-word !important;">${content}</p>`;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 确保强制使用行内样式
|
|
|
|
|
processedHtml = processedHtml.replace(
|
|
|
|
|
/<strong/g,
|
|
|
|
|
'<strong style="font-weight:900 !important;display:inline !important;white-space:normal !important;word-break:normal !important;overflow-wrap:break-word !important;color:inherit !important;"'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 处理可能的HTML转义问题
|
|
|
|
|
processedHtml = processedHtml
|
|
|
|
|
.replace(/<strong/g, '<strong')
|
|
|
|
|
.replace(/<\/strong>/g, '</strong>');
|
|
|
|
|
|
|
|
|
|
// 添加强制粗体样式覆盖
|
|
|
|
|
processedHtml = `
|
|
|
|
|
<style>
|
|
|
|
|
strong, .custom-strong, b {
|
|
|
|
|
font-weight: 900 !important;
|
|
|
|
|
display: inline !important;
|
|
|
|
|
color: inherit !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
word-break: normal !important;
|
|
|
|
|
overflow-wrap: break-word !important;
|
|
|
|
|
}
|
|
|
|
|
p, div, span {
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
word-break: normal !important;
|
|
|
|
|
overflow-wrap: break-word !important;
|
|
|
|
|
text-align: left !important; /* 左对齐 */
|
|
|
|
|
text-justify: none !important; /* 禁用两端对齐 */
|
|
|
|
|
}
|
|
|
|
|
/* 关键样式:确保文本流不被打断 */
|
|
|
|
|
p strong, p b, strong, b {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
}
|
|
|
|
|
/* 针对段落内部元素的处理 */
|
|
|
|
|
p > * {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
}
|
|
|
|
|
/* 链接样式 */
|
|
|
|
|
a {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
word-break: break-all !important;
|
|
|
|
|
letter-spacing: normal !important; /* 正常字间距 */
|
|
|
|
|
word-spacing: normal !important; /* 正常词间距 */
|
|
|
|
|
text-align: left !important; /* 左对齐 */
|
|
|
|
|
}
|
2025-07-15 14:39:22 +08:00
|
|
|
|
/* 表格样式 */
|
|
|
|
|
table {
|
|
|
|
|
border-collapse: collapse !important;
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
margin: 16rpx 0 !important;
|
|
|
|
|
table-layout: fixed !important;
|
|
|
|
|
border: 1px solid #e0e0e0 !important;
|
|
|
|
|
overflow-x: auto !important;
|
|
|
|
|
}
|
|
|
|
|
th, td {
|
|
|
|
|
border: 1px solid #e0e0e0 !important;
|
|
|
|
|
padding: 12rpx !important;
|
|
|
|
|
text-align: left !important;
|
|
|
|
|
word-break: break-word !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
font-size: 28rpx !important;
|
|
|
|
|
}
|
|
|
|
|
th {
|
|
|
|
|
background-color: #f5f5f5 !important;
|
|
|
|
|
font-weight: bold !important;
|
|
|
|
|
}
|
2025-07-15 09:21:35 +08:00
|
|
|
|
/* 禁用所有可能导致文本被拉伸的样式 */
|
|
|
|
|
* {
|
|
|
|
|
text-align-last: left !important;
|
|
|
|
|
text-justify: none !important;
|
|
|
|
|
text-align: left !important;
|
|
|
|
|
letter-spacing: normal !important;
|
|
|
|
|
word-spacing: normal !important;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
` + processedHtml;
|
2025-07-10 08:52:41 +08:00
|
|
|
|
|
|
|
|
|
// 返回带样式的HTML
|
2025-07-15 09:21:35 +08:00
|
|
|
|
return styleTag + processedHtml;
|
2025-07-10 08:52:41 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Markdown渲染错误:', error);
|
2025-07-10 10:48:28 +08:00
|
|
|
|
return `<p style="color: red;">Markdown渲染错误: ${error.message}</p>`;
|
2025-07-10 08:52:41 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
@import './highlight.css';
|
|
|
|
|
|
|
|
|
|
.markdown-container {
|
|
|
|
|
padding: 20rpx;
|
2025-07-11 15:58:10 +08:00
|
|
|
|
overflow-wrap: break-word;
|
|
|
|
|
word-wrap: break-word;
|
2025-07-15 09:21:35 +08:00
|
|
|
|
word-break: normal;
|
2025-07-11 15:58:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 09:21:35 +08:00
|
|
|
|
/* 全局样式 */
|
2025-07-11 15:58:10 +08:00
|
|
|
|
.markdown-container >>> * {
|
2025-07-14 10:27:41 +08:00
|
|
|
|
max-width: 100% !important;
|
2025-07-11 15:58:10 +08:00
|
|
|
|
white-space: normal !important;
|
2025-07-15 09:21:35 +08:00
|
|
|
|
word-break: normal !important;
|
2025-07-11 15:58:10 +08:00
|
|
|
|
overflow-wrap: break-word !important;
|
2025-07-15 09:21:35 +08:00
|
|
|
|
box-sizing: border-box !important;
|
2025-07-11 15:58:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 09:21:35 +08:00
|
|
|
|
/* 段落样式 */
|
|
|
|
|
.markdown-container >>> .custom-paragraph,
|
2025-07-14 10:27:41 +08:00
|
|
|
|
.markdown-container >>> p {
|
2025-07-15 09:21:35 +08:00
|
|
|
|
display: block !important;
|
|
|
|
|
/* margin: 10rpx 0 !important; */
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
line-height: 1.6 !important;
|
|
|
|
|
text-align: left !important; /* 改为左对齐,不要两端对齐 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 专门用于列表项内容包装的容器 */
|
|
|
|
|
.markdown-container >>> .list-item-wrapper {
|
2025-07-14 10:27:41 +08:00
|
|
|
|
display: inline-block !important;
|
2025-07-15 09:21:35 +08:00
|
|
|
|
width: 100% !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
/* 关键属性:防止内部元素分列 */
|
|
|
|
|
table-layout: fixed !important;
|
|
|
|
|
word-break: normal !important;
|
2025-07-14 10:27:41 +08:00
|
|
|
|
text-align: left !important;
|
2025-07-15 09:21:35 +08:00
|
|
|
|
text-justify: none !important;
|
|
|
|
|
letter-spacing: normal !important;
|
|
|
|
|
word-spacing: normal !important;
|
|
|
|
|
text-align-last: left !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 内联元素修复 */
|
|
|
|
|
.markdown-container >>> span,
|
|
|
|
|
.markdown-container >>> a,
|
|
|
|
|
.markdown-container >>> em,
|
|
|
|
|
.markdown-container >>> strong,
|
|
|
|
|
.markdown-container >>> .custom-strong,
|
|
|
|
|
.markdown-container >>> b {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
vertical-align: baseline !important;
|
|
|
|
|
float: none !important;
|
|
|
|
|
position: static !important;
|
|
|
|
|
width: auto !important;
|
|
|
|
|
height: auto !important;
|
|
|
|
|
/* 确保内部不会有奇怪的换行 */
|
2025-07-15 09:36:19 +08:00
|
|
|
|
/* 下面不注释的话会有奇怪的换行 */
|
|
|
|
|
/* word-break: keep-all !important; */
|
2025-07-15 09:21:35 +08:00
|
|
|
|
line-height: inherit !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 特别针对粗体文本 */
|
|
|
|
|
.markdown-container >>> .custom-strong,
|
|
|
|
|
.markdown-container >>> strong,
|
|
|
|
|
.markdown-container >>> b {
|
|
|
|
|
font-weight: 900 !important;
|
|
|
|
|
display: inline !important;
|
|
|
|
|
vertical-align: baseline !important;
|
|
|
|
|
position: static !important;
|
|
|
|
|
margin: 0 !important;
|
|
|
|
|
padding: 0 !important;
|
|
|
|
|
border: none !important;
|
|
|
|
|
float: none !important;
|
|
|
|
|
width: auto !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
word-break: normal !important;
|
|
|
|
|
overflow-wrap: break-word !important;
|
|
|
|
|
word-wrap: normal !important;
|
|
|
|
|
line-height: inherit !important;
|
|
|
|
|
color: inherit !important; /* 确保颜色正确继承 */
|
|
|
|
|
font-size: inherit !important; /* 确保字体大小正确继承 */
|
|
|
|
|
font-family: inherit !important; /* 确保字体系列正确继承 */
|
|
|
|
|
text-decoration: none !important;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 14:39:22 +08:00
|
|
|
|
/* 专门修复mp-html组件生成的列表结构 */
|
|
|
|
|
.markdown-container >>> div[data-v-7e5387f] {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 处理列表编号所在的容器 - 重要修复 */
|
|
|
|
|
.markdown-container >>> div[data-v-7e5387f] {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
white-space: nowrap !important; /* 防止编号和首个字符分开 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 首行缩进优化(确保列表项不会被意外截断) */
|
|
|
|
|
.markdown-container >>> div div {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 09:21:35 +08:00
|
|
|
|
/* 有序列表样式 */
|
|
|
|
|
.markdown-container >>> .custom-ordered-list,
|
|
|
|
|
.markdown-container >>> ol {
|
|
|
|
|
display: block !important;
|
|
|
|
|
counter-reset: item !important;
|
|
|
|
|
padding-left: 0 !important;
|
|
|
|
|
margin: 10rpx 0 !important;
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
list-style-type: none !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 无序列表样式 */
|
|
|
|
|
.markdown-container >>> .custom-unordered-list,
|
|
|
|
|
.markdown-container >>> ul {
|
|
|
|
|
display: block !important;
|
|
|
|
|
padding-left: 0 !important;
|
|
|
|
|
margin: 10rpx 0 !important;
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
list-style-type: none !important;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 14:39:22 +08:00
|
|
|
|
/* 针对mp-html生成的列表标记容器 */
|
|
|
|
|
.markdown-container >>> div[style*="undefined"] {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
white-space: nowrap !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 对列表项第一个元素特殊处理 */
|
|
|
|
|
.markdown-container >>> h4 {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
margin: 0 !important;
|
|
|
|
|
padding: 0 !important;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 09:21:35 +08:00
|
|
|
|
/* 列表项共用样式 */
|
|
|
|
|
.markdown-container >>> .custom-list-item,
|
|
|
|
|
.markdown-container >>> ol li,
|
|
|
|
|
.markdown-container >>> ul li {
|
|
|
|
|
display: flex !important;
|
|
|
|
|
padding-left: 0 !important;
|
|
|
|
|
margin-bottom: 8rpx !important;
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
position: relative !important;
|
|
|
|
|
/* 确保内容在一行显示 */
|
|
|
|
|
flex-wrap: nowrap !important;
|
|
|
|
|
align-items: flex-start !important; /* 顶部对齐 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 列表项内容样式 */
|
|
|
|
|
.markdown-container >>> .custom-list-item > *:not(ol):not(ul),
|
|
|
|
|
.markdown-container >>> ol li > *:not(ol):not(ul),
|
|
|
|
|
.markdown-container >>> ul li > *:not(ol):not(ul) {
|
|
|
|
|
flex: 1 !important;
|
|
|
|
|
display: inline !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
word-break: normal !important;
|
|
|
|
|
width: auto !important;
|
|
|
|
|
/* 确保文本不会被分列 */
|
|
|
|
|
column-count: 1 !important;
|
|
|
|
|
column-width: auto !important;
|
|
|
|
|
column-span: all !important;
|
|
|
|
|
text-align: left !important; /* 确保文本左对齐 */
|
|
|
|
|
justify-content: flex-start !important; /* 左对齐 */
|
|
|
|
|
text-justify: none !important; /* 禁用两端对齐 */
|
|
|
|
|
letter-spacing: normal !important; /* 正常字间距 */
|
|
|
|
|
word-spacing: normal !important; /* 正常词间距 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 列表项内的p标签特殊处理 */
|
|
|
|
|
.markdown-container >>> ol li p,
|
|
|
|
|
.markdown-container >>> ul li p,
|
|
|
|
|
.markdown-container >>> .custom-list-item p {
|
|
|
|
|
display: inline !important;
|
|
|
|
|
margin: 0 !important;
|
|
|
|
|
padding: 0 !important;
|
|
|
|
|
width: auto !important;
|
|
|
|
|
white-space: normal !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 有序列表项编号 */
|
|
|
|
|
.markdown-container >>> .custom-ordered-list > .custom-list-item::before,
|
|
|
|
|
.markdown-container >>> ol > li::before {
|
|
|
|
|
counter-increment: item !important;
|
|
|
|
|
content: counter(item)"." !important;
|
|
|
|
|
min-width: 40rpx !important;
|
|
|
|
|
width: 40rpx !important;
|
|
|
|
|
font-weight: bold !important;
|
|
|
|
|
text-align: right !important;
|
|
|
|
|
margin-right: 8rpx !important;
|
|
|
|
|
padding-right: 0 !important;
|
|
|
|
|
flex-shrink: 0 !important;
|
|
|
|
|
align-self: flex-start !important; /* 顶部对齐 */
|
|
|
|
|
/* padding-top: 1rpx !important; 微调垂直位置 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 无序列表项标记 */
|
|
|
|
|
.markdown-container >>> .custom-unordered-list > .custom-list-item::before,
|
|
|
|
|
.markdown-container >>> ul > li::before {
|
|
|
|
|
content: "-" !important;
|
|
|
|
|
min-width: 40rpx !important;
|
|
|
|
|
width: 40rpx !important;
|
|
|
|
|
font-weight: bold !important;
|
|
|
|
|
text-align: center !important;
|
|
|
|
|
margin-right: 8rpx !important;
|
|
|
|
|
padding-right: 0 !important;
|
|
|
|
|
flex-shrink: 0 !important;
|
|
|
|
|
align-self: flex-start !important; /* 顶部对齐 */
|
|
|
|
|
/* padding-top: 1rpx !important; 微调垂直位置 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 禁用可能导致问题的CSS特性 */
|
|
|
|
|
.markdown-container >>> * {
|
|
|
|
|
column-count: 1 !important;
|
|
|
|
|
column-gap: 0 !important;
|
|
|
|
|
column-rule: none !important;
|
|
|
|
|
column-span: all !important;
|
|
|
|
|
column-width: auto !important;
|
|
|
|
|
columns: auto !important;
|
2025-07-14 10:27:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 09:21:35 +08:00
|
|
|
|
/* 代码块样式 */
|
2025-07-11 15:58:10 +08:00
|
|
|
|
.markdown-container >>> pre,
|
|
|
|
|
.markdown-container >>> code {
|
|
|
|
|
white-space: pre-wrap !important;
|
2025-07-15 09:21:35 +08:00
|
|
|
|
word-break: break-all !important;
|
2025-07-11 15:58:10 +08:00
|
|
|
|
overflow-wrap: break-word !important;
|
2025-07-14 10:27:41 +08:00
|
|
|
|
max-width: 100% !important;
|
2025-07-10 08:52:41 +08:00
|
|
|
|
}
|
2025-07-15 14:39:22 +08:00
|
|
|
|
|
|
|
|
|
/* 表格样式 */
|
|
|
|
|
.markdown-container >>> table {
|
|
|
|
|
border-collapse: collapse !important;
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
margin: 0 !important;
|
2025-07-15 14:53:34 +08:00
|
|
|
|
table-layout: fixed !important; /* 使用固定表格布局 */
|
2025-07-15 14:39:22 +08:00
|
|
|
|
border: 1px solid #e0e0e0 !important;
|
|
|
|
|
font-size: 24rpx !important; /* 稍微减小字体大小,适应移动端 */
|
2025-07-15 14:53:34 +08:00
|
|
|
|
overflow-x: visible !important; /* 移除溢出隐藏 */
|
2025-07-15 14:39:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.markdown-container >>> table th,
|
|
|
|
|
.markdown-container >>> table td {
|
|
|
|
|
border: 1px solid #e0e0e0 !important;
|
|
|
|
|
padding: 8rpx 10rpx !important; /* 减小内边距 */
|
|
|
|
|
text-align: left !important;
|
2025-07-15 14:53:34 +08:00
|
|
|
|
word-break: break-word !important; /* 确保长文本会自动换行 */
|
2025-07-15 14:39:22 +08:00
|
|
|
|
white-space: normal !important;
|
|
|
|
|
vertical-align: middle !important;
|
|
|
|
|
min-width: 80rpx !important; /* 设置最小宽度 */
|
2025-07-15 14:53:34 +08:00
|
|
|
|
max-width: none !important; /* 移除最大宽度限制 */
|
|
|
|
|
width: auto !important; /* 使列宽自动调整 */
|
|
|
|
|
overflow-wrap: break-word !important; /* 确保长单词会换行 */
|
2025-07-15 14:39:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.markdown-container >>> table th {
|
|
|
|
|
background-color: #f5f5f5 !important;
|
|
|
|
|
font-weight: bold !important;
|
|
|
|
|
color: #333333 !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.markdown-container >>> table tr:nth-child(even) {
|
|
|
|
|
background-color: #fafafa !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.markdown-container >>> table tr:hover {
|
|
|
|
|
background-color: #f0f0f0 !important;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 14:53:34 +08:00
|
|
|
|
/* 表格容器 - 移除水平滚动 */
|
2025-07-15 14:39:22 +08:00
|
|
|
|
.markdown-container >>> .table-container {
|
|
|
|
|
width: 100% !important;
|
2025-07-15 14:53:34 +08:00
|
|
|
|
overflow-x: visible !important; /* 移除水平滚动 */
|
|
|
|
|
margin: 16rpx 0 30rpx !important; /* 增加底部边距,与下方内容分开 */
|
2025-07-15 14:39:22 +08:00
|
|
|
|
display: block !important;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 14:53:34 +08:00
|
|
|
|
/* 表格整体显示 */
|
2025-07-15 14:39:22 +08:00
|
|
|
|
.markdown-container >>> .custom-table {
|
2025-07-15 14:53:34 +08:00
|
|
|
|
width: 100% !important;
|
|
|
|
|
table-layout: fixed !important; /* 固定布局 */
|
|
|
|
|
overflow: visible !important; /* 显示所有内容 */
|
2025-07-15 14:39:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 表格标题 */
|
|
|
|
|
.markdown-container >>> table caption {
|
|
|
|
|
font-weight: bold !important;
|
|
|
|
|
padding: 10rpx !important;
|
|
|
|
|
caption-side: top !important;
|
|
|
|
|
text-align: center !important;
|
|
|
|
|
color: #333333 !important;
|
|
|
|
|
}
|
2025-07-15 14:53:34 +08:00
|
|
|
|
|
|
|
|
|
/* 分隔线样式优化 */
|
|
|
|
|
.markdown-container >>> hr {
|
|
|
|
|
display: block !important;
|
|
|
|
|
height: 2rpx !important;
|
|
|
|
|
border: 0 !important;
|
|
|
|
|
border-top: 2rpx solid #e0e0e0 !important;
|
|
|
|
|
margin: 24rpx 0 !important; /* 增加上下边距 */
|
|
|
|
|
padding: 0 !important;
|
|
|
|
|
clear: both !important;
|
|
|
|
|
background-color: #e0e0e0 !important;
|
|
|
|
|
}
|
2025-07-10 08:52:41 +08:00
|
|
|
|
</style>
|