feat: code copying and guide for alternative syntax highlighting methods
This commit is contained in:
parent
127e297e75
commit
ff91324a79
2 changed files with 104 additions and 0 deletions
84
src/components/CodeScript.astro
Normal file
84
src/components/CodeScript.astro
Normal file
|
@ -0,0 +1,84 @@
|
|||
---
|
||||
// from https://www.jaluwibowo.id/blog/en/custom-syntax-highlight-and-copy-feature/
|
||||
---
|
||||
<script>
|
||||
function renderCodeLang(preBlock) {
|
||||
const lang = preBlock.dataset.language;
|
||||
|
||||
if (lang !== 'plaintext') {
|
||||
// add lang section on top left
|
||||
const langSection = document.createElement("div");
|
||||
langSection.className = "code-lang";
|
||||
langSection.innerHTML = lang;
|
||||
|
||||
preBlock.prepend(langSection);
|
||||
}
|
||||
}
|
||||
const copyImg = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M9 18q-.825 0-1.413-.588T7 16V4q0-.825.588-1.413T9 2h9q.825 0 1.413.588T20 4v12q0 .825-.588 1.413T18 18H9Zm0-2h9V4H9v12Zm-4 6q-.825 0-1.413-.588T3 20V7q0-.425.288-.713T4 6q.425 0 .713.288T5 7v13h10q.425 0 .713.288T16 21q0 .425-.288.713T15 22H5Zm4-6V4v12Z"/></svg>`
|
||||
const checkMarkImg = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="m10.6 16.2l7.05-7.05l-1.4-1.4l-5.65 5.65l-2.85-2.85l-1.4 1.4l4.25 4.25ZM5 21q-.825 0-1.413-.588T3 19V5q0-.825.588-1.413T5 3h14q.825 0 1.413.588T21 5v14q0 .825-.588 1.413T19 21H5Z"/></svg>`
|
||||
|
||||
function renderCopyBtn(preBlock) {
|
||||
const copyButton = document.createElement("button");
|
||||
|
||||
copyButton.className = "copy-code";
|
||||
copyButton.setAttribute("aria-label", "Copy code to clipboard");
|
||||
copyButton.setAttribute("title", "Copy code to clipboard");
|
||||
copyButton.innerHTML = copyImg;
|
||||
|
||||
preBlock.appendChild(copyButton);
|
||||
|
||||
copyButton.addEventListener("click", async () => {
|
||||
await copyCode(preBlock, copyButton);
|
||||
});
|
||||
}
|
||||
async function copyCode(block, button) {
|
||||
const code = block.querySelector("code");
|
||||
const text = code?.innerText || "";
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
||||
// Visual feedback that the task is completed
|
||||
button.innerHTML = checkMarkImg;
|
||||
|
||||
setTimeout(() => {
|
||||
button.innerHTML = copyImg;
|
||||
}, 700);
|
||||
} catch (error) {
|
||||
console.error("Failed to copy code: ", error);
|
||||
}
|
||||
}
|
||||
const preBlocks = Array.from(document.querySelectorAll("pre"));
|
||||
|
||||
for (const preBlock of preBlocks) {
|
||||
preBlock.style.position = "relative";
|
||||
|
||||
renderCodeLang(preBlock);
|
||||
renderCopyBtn(preBlock);
|
||||
}
|
||||
</script>
|
||||
<style is:inline>
|
||||
.code-lang {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 85%;
|
||||
color: #e5e9f0;
|
||||
padding: 0.25rem 0.5rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
border-radius: 0 0 0.25rem 0.25rem;
|
||||
}
|
||||
|
||||
.copy-code {
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
outline: inherit;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
background-color: rgba(67, 76, 94, 0.75);
|
||||
color: #d8dee9;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
</style>
|
Loading…
Add table
Add a link
Reference in a new issue