diff --git a/config.toml b/config.toml
index 7f447a4..7f6c53a 100644
--- a/config.toml
+++ b/config.toml
@@ -48,6 +48,10 @@ source_url = "https://codeberg.org/daudix/duckquill"
# "YOUR_STYLE.css",
# "ALSO_YOUR_STYLE.css"
# ]
+# Whether to display "copy code" button on all code blocks
+# that have the language set.
+# See https://www.getzola.org/documentation/content/syntax-highlighting/
+show_copy_button = true
[extra.nav]
# Whether to show Atom/RSS feed button in the nav
@@ -88,7 +92,7 @@ show_johnvert = false
# Whether to show "Powered by Zola and Duckquill"
show_powered_by = true
# Whether to show link to website source
-show_source = true
+show_source = false
# Based on https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/
#
diff --git a/sass/_main.scss b/sass/_main.scss
index 823901f..274af40 100644
--- a/sass/_main.scss
+++ b/sass/_main.scss
@@ -193,6 +193,61 @@ pre {
overflow: auto;
line-height: normal; // Unset line height
+ &[class*="language-"] {
+ position: relative;
+
+ & button {
+ all: unset;
+ display: inline-flex;
+ position: absolute;
+ top: 0.5rem;
+ right: 0.5rem;
+ transition: var(--transition);
+ border-radius: 50%;
+ background-color: var(--fg-muted-1);
+ padding: 0.5rem;
+ width: 1rem;
+ height: 1rem;
+ cursor: pointer;
+
+ &:hover {
+ background-color: var(--fg-muted-2);
+
+ i {
+ background-color: var(--fg-muted-5);
+ }
+ }
+
+ &:active {
+ transform: scale(var(--active));
+ }
+
+ &.active {
+ background-color: var(--primary-color-alpha);
+
+ i {
+ background-color: var(--primary-color);
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M7.883 0q-.486.008-.965.074a7.98 7.98 0 0 0-4.602 2.293 8.01 8.01 0 0 0-1.23 9.664 8.015 8.015 0 0 0 9.02 3.684 8 8 0 0 0 5.89-7.75 1 1 0 1 0-2 .008 5.986 5.986 0 0 1-4.418 5.816 5.996 5.996 0 0 1-6.762-2.766 5.99 5.99 0 0 1 .922-7.25 5.99 5.99 0 0 1 7.239-.984 1 1 0 0 0 1.363-.371c.273-.48.11-1.09-.371-1.367A8 8 0 0 0 9.492.14 8 8 0 0 0 7.882 0m7.15 1.998-.1.002a1 1 0 0 0-.687.34L7.95 9.535 5.707 7.29A1 1 0 0 0 4 8a1 1 0 0 0 .293.707l3 3c.195.195.465.3.742.293.277-.012.535-.133.719-.344l7-8A1 1 0 0 0 16 2.934a1 1 0 0 0-.34-.688 1 1 0 0 0-.627-.248'/%3E%3C/svg%3E");
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M7.883 0q-.486.008-.965.074a7.98 7.98 0 0 0-4.602 2.293 8.01 8.01 0 0 0-1.23 9.664 8.015 8.015 0 0 0 9.02 3.684 8 8 0 0 0 5.89-7.75 1 1 0 1 0-2 .008 5.986 5.986 0 0 1-4.418 5.816 5.996 5.996 0 0 1-6.762-2.766 5.99 5.99 0 0 1 .922-7.25 5.99 5.99 0 0 1 7.239-.984 1 1 0 0 0 1.363-.371c.273-.48.11-1.09-.371-1.367A8 8 0 0 0 9.492.14 8 8 0 0 0 7.882 0m7.15 1.998-.1.002a1 1 0 0 0-.687.34L7.95 9.535 5.707 7.29A1 1 0 0 0 4 8a1 1 0 0 0 .293.707l3 3c.195.195.465.3.742.293.277-.012.535-.133.719-.344l7-8A1 1 0 0 0 16 2.934a1 1 0 0 0-.34-.688 1 1 0 0 0-.627-.248'/%3E%3C/svg%3E");
+ }
+ }
+
+ i {
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' height='16' width='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 3c0-1.645 1.355-3 3-3h5c1.645 0 3 1.355 3 3 0 .55-.45 1-1 1s-1-.45-1-1c0-.57-.43-1-1-1H3c-.57 0-1 .43-1 1v5c0 .57.43 1 1 1 .55 0 1 .45 1 1s-.45 1-1 1c-1.645 0-3-1.355-3-3zm5 5c0-1.645 1.355-3 3-3h5c1.645 0 3 1.355 3 3v5c0 1.645-1.355 3-3 3H8c-1.645 0-3-1.355-3-3zm2 0v5c0 .57.43 1 1 1h5c.57 0 1-.43 1-1V8c0-.57-.43-1-1-1H8c-.57 0-1 .43-1 1m0 0'/%3E%3C/svg%3E");
+ display: inline-block;
+ mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' height='16' width='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 3c0-1.645 1.355-3 3-3h5c1.645 0 3 1.355 3 3 0 .55-.45 1-1 1s-1-.45-1-1c0-.57-.43-1-1-1H3c-.57 0-1 .43-1 1v5c0 .57.43 1 1 1 .55 0 1 .45 1 1s-.45 1-1 1c-1.645 0-3-1.355-3-3zm5 5c0-1.645 1.355-3 3-3h5c1.645 0 3 1.355 3 3v5c0 1.645-1.355 3-3 3H8c-1.645 0-3-1.355-3-3zm2 0v5c0 .57.43 1 1 1h5c.57 0 1-.43 1-1V8c0-.57-.43-1-1-1H8c-.57 0-1 .43-1 1m0 0'/%3E%3C/svg%3E");
+ transition: var(--transition);
+ background-color: var(--fg-muted-4);
+ width: 1rem;
+ height: 1rem;
+ font-style: normal;
+ font-variant: normal;
+ line-height: 1;
+ text-rendering: auto;
+ }
+ }
+ }
+
table td {
border: none;
padding: 0;
diff --git a/static/copy-button.js b/static/copy-button.js
new file mode 100644
index 0000000..deda191
--- /dev/null
+++ b/static/copy-button.js
@@ -0,0 +1,31 @@
+// Based on https://www.roboleary.net/2022/01/13/copy-code-to-clipboard-blog.html
+document.addEventListener("DOMContentLoaded", function () {
+ let blocks = document.querySelectorAll("pre[class^='language-']");
+
+ blocks.forEach((block) => {
+ if (navigator.clipboard) {
+ let button = document.createElement("button");
+ let icon = document.createElement("i");
+
+ button.appendChild(icon);
+ block.appendChild(button);
+
+ button.addEventListener("click", async () => {
+ await copyCode(block, button);
+ });
+ }
+ });
+
+ async function copyCode(block, button) {
+ let code = block.querySelector("code");
+ let text = code.innerText;
+
+ await navigator.clipboard.writeText(text);
+
+ button.classList.add("active");
+
+ setTimeout(() => {
+ button.classList.remove("active");
+ }, 800);
+ }
+});
diff --git a/templates/partials/head.html b/templates/partials/head.html
index 3d60f02..aa06c38 100644
--- a/templates/partials/head.html
+++ b/templates/partials/head.html
@@ -33,6 +33,10 @@
}
+ {% if config.extra.show_copy_button %}
+
+ {% endif %}
+
{% if config.extra.comments %}
{% endif %}