feat: 优化 Markdown 代码块高亮样式及渲染逻辑
This commit is contained in:
1 parent
d4f113c77b
commit
81dd62c3df
2 files changed
+50
-12
No files matched your search
+14
@@ -1,3 +1,4 @@
|
|||||||
|
@import "highlight.js/styles/github.css";
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--bg-color: #ffffff;
|
--bg-color: #ffffff;
|
||||||
@@ -601,6 +602,19 @@ body.single-col .post-list {
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-header-actions button span {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-header-actions svg {
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 操作按钮:默认隐藏,展开时显示 */
|
/* 操作按钮:默认隐藏,展开时显示 */
|
||||||
|
|||||||
@@ -15,16 +15,40 @@
|
|||||||
renderer: {
|
renderer: {
|
||||||
code(token) {
|
code(token) {
|
||||||
const code = token.text;
|
const code = token.text;
|
||||||
const lang = (token.lang || '').split(' ')[0];
|
const rawLang = (token.lang || '').trim().toLowerCase().split(' ')[0];
|
||||||
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
|
let highlighted: string;
|
||||||
const highlighted = hljs.highlight(code, { language }).value;
|
let language = 'plaintext';
|
||||||
const title = lang || 'text';
|
|
||||||
|
if (rawLang && hljs.getLanguage(rawLang)) {
|
||||||
|
language = rawLang;
|
||||||
|
highlighted = hljs.highlight(code, { language }).value;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const auto = hljs.highlightAuto(code);
|
||||||
|
highlighted = auto.value || code;
|
||||||
|
if (auto.language) language = auto.language;
|
||||||
|
} catch {
|
||||||
|
highlighted = code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const title = rawLang || language || 'text';
|
||||||
const encodedCode = encodeURIComponent(code);
|
const encodedCode = encodeURIComponent(code);
|
||||||
|
|
||||||
const wrappedLines = highlighted
|
const lines = highlighted.split('\n');
|
||||||
.split('\n')
|
const openSpans: string[] = [];
|
||||||
.map((line) => `<span class="code-line">${line}</span>`)
|
const wrappedLines = lines.map((line) => {
|
||||||
.join('\n');
|
const prefix = openSpans.join('');
|
||||||
|
const matches = line.matchAll(/<span [^>]+>|<\/span>/g);
|
||||||
|
for (const m of matches) {
|
||||||
|
if (m[0] === '</span>') {
|
||||||
|
openSpans.pop();
|
||||||
|
} else {
|
||||||
|
openSpans.push(m[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const suffix = '</span>'.repeat(openSpans.length);
|
||||||
|
return `<span class="code-line">${prefix}${line}${suffix}</span>`;
|
||||||
|
}).join('\n');
|
||||||
|
|
||||||
const chevronRight = '<svg class="chevron-icon" viewBox="0 0 320 512" fill="currentColor" width="0.625em" height="1em"><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"></path></svg>';
|
const chevronRight = '<svg class="chevron-icon" viewBox="0 0 320 512" fill="currentColor" width="0.625em" height="1em"><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"></path></svg>';
|
||||||
const listOlIcon = '<svg viewBox="0 0 512 512" fill="currentColor" width="1em" height="1em"><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"></path></svg>';
|
const listOlIcon = '<svg viewBox="0 0 512 512" fill="currentColor" width="1em" height="1em"><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"></path></svg>';
|
||||||
@@ -43,8 +67,8 @@
|
|||||||
<button class="action-icon line-number-button is-active" title="Toggle line numbers">${listOlIcon}</button>
|
<button class="action-icon line-number-button is-active" title="Toggle line numbers">${listOlIcon}</button>
|
||||||
<button class="action-icon wrap-code-button" title="Toggle code wrap">${barsIcon}</button>
|
<button class="action-icon wrap-code-button" title="Toggle code wrap">${barsIcon}</button>
|
||||||
<button class="action-icon copy-code-button" title="Copy code" data-code="${encodedCode}">
|
<button class="action-icon copy-code-button" title="Copy code" data-code="${encodedCode}">
|
||||||
<span class="copy-icon" style="display:block">${copyIcon}</span>
|
<span class="copy-icon" style="display:flex; align-items:center; justify-content:center;">${copyIcon}</span>
|
||||||
<span class="check-icon" style="display:none">${checkIcon}</span>
|
<span class="check-icon" style="display:none; align-items:center; justify-content:center;">${checkIcon}</span>
|
||||||
</button>
|
</button>
|
||||||
<span class="ellipsis-icon" aria-hidden="true">${ellipsisIcon}</span>
|
<span class="ellipsis-icon" aria-hidden="true">${ellipsisIcon}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -174,9 +198,9 @@
|
|||||||
if (codeEl) {
|
if (codeEl) {
|
||||||
navigator.clipboard.writeText(codeEl.textContent || '');
|
navigator.clipboard.writeText(codeEl.textContent || '');
|
||||||
if (copyIconEl) copyIconEl.style.display = 'none';
|
if (copyIconEl) copyIconEl.style.display = 'none';
|
||||||
if (checkIconEl) checkIconEl.style.display = 'block';
|
if (checkIconEl) checkIconEl.style.display = 'flex';
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (copyIconEl) copyIconEl.style.display = 'block';
|
if (copyIconEl) copyIconEl.style.display = 'flex';
|
||||||
if (checkIconEl) checkIconEl.style.display = 'none';
|
if (checkIconEl) checkIconEl.style.display = 'none';
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user