新增:Markdown 本地文件链接支持 + Shell 语法高亮
Markdown 预览增强: - 支持点击本地文件链接(相对路径)打开对应文件 - 支持链接文本中的加粗/斜体等内联语法 - 锚点链接保持页面内跳转,外部链接新窗口打开 代码高亮增强: - 添加 sh/bash/shell 语言别名映射 - 安装 @codemirror/legacy-modes 支持 .sh 文件语法高亮
This commit is contained in:
@@ -1,9 +1,26 @@
|
||||
import { marked } from 'marked'
|
||||
import hljs from 'highlight.js'
|
||||
import 'highlight.js/lib/common'
|
||||
// 额外导入 common 包不包含的语言
|
||||
import 'highlight.js/lib/languages/bash'
|
||||
import 'highlight.js/lib/languages/go'
|
||||
import 'highlight.js/styles/github-dark.css'
|
||||
import 'highlight.js/styles/github.css'
|
||||
|
||||
// 语言别名映射(sh -> bash 等)
|
||||
const languageAliases: Record<string, string> = {
|
||||
'sh': 'bash',
|
||||
'shell': 'bash',
|
||||
'zsh': 'bash',
|
||||
'ksh': 'bash',
|
||||
'ts': 'typescript',
|
||||
'js': 'javascript',
|
||||
'py': 'python',
|
||||
'rb': 'ruby',
|
||||
'yml': 'yaml',
|
||||
'md': 'markdown'
|
||||
}
|
||||
|
||||
let mermaidInstance: typeof import('mermaid').default | null = null
|
||||
|
||||
async function loadMermaid() {
|
||||
@@ -30,7 +47,15 @@ renderer.code = function(token: any) {
|
||||
return `<pre class="mermaid">${token.text}</pre>`
|
||||
}
|
||||
|
||||
const lang = hljs.getLanguage(token.lang) ? token.lang : 'plaintext'
|
||||
// 获取语言,支持别名
|
||||
let lang = token.lang || 'plaintext'
|
||||
lang = languageAliases[lang] || lang
|
||||
|
||||
// 检查语言是否支持
|
||||
if (!hljs.getLanguage(lang)) {
|
||||
lang = 'plaintext'
|
||||
}
|
||||
|
||||
const highlighted = hljs.highlight(token.text, { language: lang }).value
|
||||
return `<pre><code class="hljs language-${lang}" data-theme="auto">${highlighted}</code></pre>`
|
||||
}
|
||||
@@ -53,6 +78,40 @@ renderer.heading = function(token: any) {
|
||||
</h${depth}>`
|
||||
}
|
||||
|
||||
// 判断是否为本地文件链接(相对路径或本地绝对路径)
|
||||
const isLocalFileLink = (href: string): boolean => {
|
||||
if (!href) return false
|
||||
// 排除 http/https/ftp/mailto 等外部链接
|
||||
if (/^(https?|ftp|mailto|tel|data):/i.test(href)) return false
|
||||
// 排除锚点链接
|
||||
if (href.startsWith('#')) return false
|
||||
// 相对路径或本地路径(如 ./file.md, ../file.md, /path/to/file, C:\path\file)
|
||||
return true
|
||||
}
|
||||
|
||||
// 自定义链接渲染器 - 支持本地文件链接
|
||||
renderer.link = function(token: any) {
|
||||
const href = token.href || ''
|
||||
// 解析链接文本中的内联元素(如加粗、斜体等)
|
||||
const text = this.parser.parseInline(token.tokens) || token.text || ''
|
||||
const title = token.title || ''
|
||||
|
||||
const titleAttr = title ? ` title="${title}"` : ''
|
||||
|
||||
// 锚点链接 - 保持原样,页面内跳转
|
||||
if (href.startsWith('#')) {
|
||||
return `<a href="${href}"${titleAttr}>${text}</a>`
|
||||
}
|
||||
|
||||
// 判断是否为本地文件链接
|
||||
if (isLocalFileLink(href)) {
|
||||
return `<a href="javascript:void(0)" data-local-link="${href}" class="local-file-link"${titleAttr}>${text}</a>`
|
||||
}
|
||||
|
||||
// 外部链接使用默认行为
|
||||
return `<a href="${href}" target="_blank" rel="noopener noreferrer"${titleAttr}>${text}</a>`
|
||||
}
|
||||
|
||||
marked.use({ renderer, breaks: true, gfm: true })
|
||||
|
||||
export { marked }
|
||||
|
||||
Reference in New Issue
Block a user