Categories
blog wordpress

blockquote – copy and code style

<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>