Skip to content

Commit

Permalink
for litedown's fenced chunk output, copy the whole chunk's source ins…
Browse files Browse the repository at this point in the history
…tead of an individual code block
  • Loading branch information
yihui committed Apr 22, 2024
1 parent e0797f9 commit d644932
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
9 changes: 8 additions & 1 deletion css/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,18 @@ pre code {
overflow-x: auto;
}
code { font-family: 'DejaVu Sans Mono', 'Droid Sans Mono', 'Lucida Console', Consolas, Monaco, monospace; }
:not(pre) > code, code[class] { background-color: #F8F8F8; }
:not(pre) > code, code[class] { background-color: #f8f8f8; }
code.language-undefined, pre > code:not([class]) {
background-color: inherit;
border: 1px solid #eee;
}
.fenced-chunk { border-left: 1px solid #666; }
.code-fence {
opacity: .4;
border: 1px dashed #666;
border-left: 2px solid;
}
.code-fence:hover { opacity: inherit; }
table {
margin: auto;
border-top: 1px solid #666;
Expand Down
13 changes: 10 additions & 3 deletions js/copy-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@
const cfg = d.currentScript?.dataset;
d.querySelectorAll(cfg?.selector || 'pre>code').forEach(el => {
const btn = d.createElement('span'), cls = btn.classList,
c1 = 'copy-success', c2 = 'copy-fail';
c1 = 'copy-success', c2 = 'copy-fail', pre = el.parentNode,
is_code = el.tagName === 'CODE' && pre?.tagName === 'PRE';
btn.className = 'copy-button';
// temporarily add a class to the button (as a feedback to copy action)
function feedback(c) {
cls.add(c); setTimeout(() => cls.remove(c), 1000);
}
btn.onclick = () => navigator.clipboard.writeText(el.innerText).then(
// for code.code-fence in div.fenced-chunk (from litedown), copy the whole chunk's source
function getText() {
return (is_code && el.classList.contains('code-fence') && pre.parentNode?.classList.contains('fenced-chunk')) ?
[...pre.parentNode.querySelectorAll('code[class]')]
.map(code => code.innerText.replace(/\n$/, '')).join('\n') : el.innerText;
}
btn.onclick = () => navigator.clipboard.writeText(getText()).then(
() => feedback(c1), () => feedback(c2)
);
// add the button to <pre> for <code> because <code>'s innerHTML' may be
// changed later, e.g., by syntax highlighting libraries
const p = (el.tagName === 'CODE' && el?.parentNode.tagName === 'PRE') ? el.parentNode : el;
const p = is_code ? pre : el;
// add the button only if it has not been added
p.querySelector('.copy-button') || p.append(btn);
getComputedStyle(p).position === 'static' && (p.style.position = 'relative');
Expand Down

0 comments on commit d644932

Please sign in to comment.