<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
function setupCodeBlock(block, lang = '') {
block.style.position = 'relative';
// Collect all child lines
let codeEls = Array.from(block.querySelectorAll('div, p, span'));
if (codeEls.length === 0) codeEls = [block];
// Generate raw code text with indentation
let rawCode = '';
let indentLevel = 0;
codeEls.forEach(el => {
let text = el.textContent.trim();
if (text.includes('}')) indentLevel = Math.max(indentLevel - 1, 0);
rawCode += ' '.repeat(indentLevel) + text + '\n'; // 4 spaces per indent
if (text.includes('{')) indentLevel++;
});
// Create <pre><code> for Highlight.js
const pre = document.createElement('pre');
const code = document.createElement('code');
code.className = lang + ' hljs';
code.textContent = rawCode.replace(/[“”]/g,'"').replace(/[‘’]/g,"'");
pre.appendChild(code);
// Clear old content and append new
while (block.firstChild) block.removeChild(block.firstChild);
block.appendChild(pre);
// Highlight.js
hljs.highlightElement(code);
// Create copy button
const copyBtn = document.createElement('button');
copyBtn.className = 'copy-btn';
copyBtn.innerText = 'Copy';
block.appendChild(copyBtn);
// Copy button event
copyBtn.addEventListener('click', () => {
navigator.clipboard.writeText(code.textContent).then(() => {
copyBtn.innerText = 'Copied!';
setTimeout(() => copyBtn.innerText = 'Copy', 1500);
});
});
}
// Apply to all spoiler-body
document.querySelectorAll('.spoiler-body').forEach(block => {
const langSpan = block.closest('.spoiler').querySelector('.spoiler-head span');
const lang = langSpan ? langSpan.textContent.toLowerCase() : '';
setupCodeBlock(block, lang);
});
});
</script>
<style>
.hljs {
background: transparent;
}
.post-message blockquote,
.spoiler-body {
background: #0d1117;
color: #c9d1d9;
padding: 14px;
border-radius: 6px;
line-height: 18px;
overflow-x: auto;
tab-size: 4;
font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace;
font-size: 14px;
white-space: pre; /* preserve tabs and spaces */
margin: 1em 0;
position: relative;
}
.post-message blockquote div,
.post-message blockquote p,
.post-message blockquote span,
.spoiler-body div,
.spoiler-body p,
.spoiler-body span {
margin: 0;
}
#af-wrapper .spoiler .spoiler-body {
margin: 0px;
}
.copy-btn {
position: absolute;
top: 8px;
right: 8px;
background: #161b22;
border: 1px solid #30363d;
color: #c9d1d9;
padding: 4px 10px;
font-size: 12px;
border-radius: 6px;
cursor: pointer;
opacity: 0;
transition: opacity 0.2s ease-in-out, background 0.2s;
}
.post-message blockquote:hover .copy-btn,
.spoiler-body:hover .copy-btn,
.copy-btn:hover {
opacity: 1;
}
.copy-btn:hover {
background: #21262d;
}
.copy-btn {
position: absolute;
top: 8px;
right: 8px;
background: #161b22;
border: 1px solid #30363d;
color: #c9d1d9;
padding: 4px 10px;
font-size: 12px;
border-radius: 6px;
cursor: pointer;
opacity: 0;
transition: opacity 0.2s ease-in-out, background 0.2s;
}
.spoiler-body:hover .copy-btn,
.copy-btn:hover {
opacity: 1;
}
.copy-btn:hover {
background: #21262d;
}
</style>