From d44bffd81ff23e9b35b7315854a8bc818526ab76 Mon Sep 17 00:00:00 2001 From: Daniel-I-Am Date: Mon, 13 Jun 2022 00:50:12 +0200 Subject: [PATCH] Implement code blocks and groups mostly --- assets/js/app.js | 4 +++ assets/js/code-block-formatter.js | 31 ++++++++++++++++++++ assets/js/tabbed.js | 31 ++++++++++++++++++++ assets/sass/_code.scss | 47 +++++++++++++++++++++++++++++++ assets/sass/app.scss | 1 + config.toml | 4 +++ layouts/shortcodes/codegroup.html | 25 ++++++++++++++++ 7 files changed, 143 insertions(+) create mode 100644 assets/js/code-block-formatter.js create mode 100644 assets/js/tabbed.js create mode 100644 assets/sass/_code.scss create mode 100644 layouts/shortcodes/codegroup.html diff --git a/assets/js/app.js b/assets/js/app.js index 5f9d749..d088aae 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -1,6 +1,10 @@ import clickableMaker from "./clickable-maker"; +import codeBlockFormatter from "./code-block-formatter"; +import tabbed from "./tabbed"; import _ from "./lunr"; window.addEventListener('load', () => { clickableMaker(); + codeBlockFormatter(); + tabbed(); }); diff --git a/assets/js/code-block-formatter.js b/assets/js/code-block-formatter.js new file mode 100644 index 0000000..9fe4740 --- /dev/null +++ b/assets/js/code-block-formatter.js @@ -0,0 +1,31 @@ +export default function() { + Array.from(document.querySelectorAll('[data-copy-button=true]')).forEach(e => { + const copyButton = document.createElement('button'); + copyButton.classList.add('copy-button'); + + copyButton.addEventListener('click', () => { + const addTemporaryClass = (className, time) => { + copyButton.classList.add(className); + + setTimeout(() => { + if (copyButton.classList.contains(className)) { + copyButton.classList.remove(className); + } + }, time); + } + + if (!navigator || !navigator.clipboard) { + console.warn("Clipboard not accessible"); + addTemporaryClass('copy-failed', 2000); + } + + const content = e.innerText.trim(); + navigator.clipboard.writeText(content).then(() => { + addTemporaryClass('copy-successful', 2000); + }); + }); + + e.classList.add('contains-copy-button'); + e.insertBefore(copyButton, e.firstChild); + }); +} diff --git a/assets/js/tabbed.js b/assets/js/tabbed.js new file mode 100644 index 0000000..88c5808 --- /dev/null +++ b/assets/js/tabbed.js @@ -0,0 +1,31 @@ +export default function() { + Array.from(document.querySelectorAll('[data-tabbed=true]')).forEach(tabbed => { + const header = tabbed.querySelector('.tab-header'); + Array.from(header.children).forEach(element => { + element.addEventListener('click', () => { + updateTabVisibility(tabbed, element.dataset.tabIndex); + }) + }); + + updateTabVisibility(tabbed, tabbed.dataset.tabIndex); + }); +} + +function updateTabVisibility(tabgroupElement, index) { + const tabHeaderElems = tabgroupElement.querySelector('.tab-header').children; + const tabContentsElems = tabgroupElement.querySelector('.tab-content').children; + + for (const element of tabHeaderElems) { + element.classList.remove('active'); + } + + Array.from(tabHeaderElems).find(e => e.dataset.tabIndex === index).classList.add('active'); + + Array.from(tabContentsElems).forEach(e => { + if (e.dataset.tabIndex === index) { + e.style.display = "block"; + } else { + e.style.display = "none"; + } + }); +} diff --git a/assets/sass/_code.scss b/assets/sass/_code.scss new file mode 100644 index 0000000..330ed29 --- /dev/null +++ b/assets/sass/_code.scss @@ -0,0 +1,47 @@ +.highlight { + pre { + code { + white-space: pre-wrap; + } + } +} + +.contains-copy-button { + position: relative; + + .copy-button { + position: absolute; + top: 0; + right: 0; + + background-color: transparent; + border: none; + + &::after { + content: '\f328'; + color: rgba($text-color, 0.75); + + font-family: 'Font Awesome 6 Free'; + font-weight: normal; + font-style: normal; + } + + &:hover { + &::after { + color: $text-color; + } + } + + &.copy-successful { + &::after { + content: '\f46c' + } + } + + &.copy-failed { + &::after { + content: '\f00d' + } + } + } +} diff --git a/assets/sass/app.scss b/assets/sass/app.scss index 64d5e0f..c5b065a 100644 --- a/assets/sass/app.scss +++ b/assets/sass/app.scss @@ -18,3 +18,4 @@ @import "compact-list"; @import "pagination"; @import "list"; +@import "code"; diff --git a/config.toml b/config.toml index e4b7418..98a9acc 100644 --- a/config.toml +++ b/config.toml @@ -1,3 +1,7 @@ baseURL = "http://example.org/" languageCode = "en-us" title = "My New Hugo Site" + +[markup] +[markup.highlight] +style = "monokai" diff --git a/layouts/shortcodes/codegroup.html b/layouts/shortcodes/codegroup.html new file mode 100644 index 0000000..966170d --- /dev/null +++ b/layouts/shortcodes/codegroup.html @@ -0,0 +1,25 @@ +
+
+ {{ range $index, $entry := split .Inner "\n---" }} + {{ $lines := split . "\n" }} + {{ $title := index $lines 1}} + + + {{ $title }} + + + {{ end }} +
+ +
+ {{ range $index, $entry := split .Inner "\n---" }} + {{ $lines := split . "\n" }} + {{ $codeBlock := delimit (after 2 $lines) "\n" }} + +
+ {{ $codeBlock | markdownify }} +
+ + {{ end }} +
+