diff --git a/go.mod b/go.mod deleted file mode 100644 index 8548577a..00000000 --- a/go.mod +++ /dev/null @@ -1,8 +0,0 @@ -module davegallant.github.io - -go 1.21 - -require ( - github.com/davegallant/hugo-theme-gruvbox v0.0.0-20240106163015-62aac1ea9f6d // indirect - github.com/schnerring/hugo-mod-json-resume v0.0.0-20231224014047-e651a547c19a // indirect -) diff --git a/go.sum b/go.sum deleted file mode 100644 index 68692b2b..00000000 --- a/go.sum +++ /dev/null @@ -1,6 +0,0 @@ -github.com/davegallant/hugo-theme-gruvbox v0.0.0-20240102231105-90b486f98b82 h1:X9jUG5D4OyxLjT3OTsL5TN3jFdpTXyLJJcRpLbgCsSc= -github.com/davegallant/hugo-theme-gruvbox v0.0.0-20240102231105-90b486f98b82/go.mod h1:BQehNdf/SB/+bCc031OVsLECIgB9ZaN1dfUFKTeOIuo= -github.com/davegallant/hugo-theme-gruvbox v0.0.0-20240106163015-62aac1ea9f6d h1:HCGtUIiR/0t+PnuB/dYhU1ZX9rKNsEnc5EToW6vWLr0= -github.com/davegallant/hugo-theme-gruvbox v0.0.0-20240106163015-62aac1ea9f6d/go.mod h1:BQehNdf/SB/+bCc031OVsLECIgB9ZaN1dfUFKTeOIuo= -github.com/schnerring/hugo-mod-json-resume v0.0.0-20231224014047-e651a547c19a h1:EZRiOf0iW5k9lycVv3LngzSsGUxDRszYS4U7ea2r8RY= -github.com/schnerring/hugo-mod-json-resume v0.0.0-20231224014047-e651a547c19a/go.mod h1:5dixHC0WHu0w2Aqb8hsOCrIU1OBYr1w5Q6HZAmTub7Q= diff --git a/package.json b/package.json index 88ba5585..5443499b 100644 --- a/package.json +++ b/package.json @@ -1,37 +1,4 @@ { - "comments": { - "dependencies": { - "@tabler/icons": "github.com/davegallant/hugo-theme-gruvbox", - "flexsearch": "github.com/davegallant/hugo-theme-gruvbox", - "normalize.css": "github.com/davegallant/hugo-theme-gruvbox", - "prism-themes": "github.com/davegallant/hugo-theme-gruvbox", - "prismjs": "github.com/davegallant/hugo-theme-gruvbox", - "simple-icons": "github.com/schnerring/hugo-mod-json-resume", - "typeface-fira-code": "github.com/davegallant/hugo-theme-gruvbox", - "typeface-roboto-slab": "github.com/davegallant/hugo-theme-gruvbox" - }, - "devDependencies": { - "@fullhuman/postcss-purgecss": "github.com/davegallant/hugo-theme-gruvbox", - "cssnano": "github.com/davegallant/hugo-theme-gruvbox", - "eslint": "github.com/davegallant/hugo-theme-gruvbox", - "eslint-config-prettier": "github.com/davegallant/hugo-theme-gruvbox", - "eslint-plugin-prettier": "github.com/davegallant/hugo-theme-gruvbox", - "husky": "github.com/davegallant/hugo-theme-gruvbox", - "lint-staged": "github.com/davegallant/hugo-theme-gruvbox", - "markdownlint-cli": "github.com/davegallant/hugo-theme-gruvbox", - "postcss": "github.com/davegallant/hugo-theme-gruvbox", - "postcss-cli": "github.com/davegallant/hugo-theme-gruvbox", - "postcss-custom-media": "github.com/davegallant/hugo-theme-gruvbox", - "postcss-import": "github.com/davegallant/hugo-theme-gruvbox", - "postcss-nesting": "github.com/davegallant/hugo-theme-gruvbox", - "postcss-preset-env": "github.com/davegallant/hugo-theme-gruvbox", - "postcss-url": "github.com/davegallant/hugo-theme-gruvbox", - "prettier": "github.com/davegallant/hugo-theme-gruvbox", - "prettier-plugin-go-template": "github.com/davegallant/hugo-theme-gruvbox", - "stylelint": "github.com/davegallant/hugo-theme-gruvbox", - "stylelint-prettier": "github.com/davegallant/hugo-theme-gruvbox" - } - }, "dependencies": { "@tabler/icons": "^2.44.0", "flexsearch": "^0.7.31", diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.editorconfig b/themes/github.com/davegallant/hugo-theme-gruvbox/.editorconfig new file mode 100644 index 00000000..93972f20 --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space \ No newline at end of file diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.eslintignore b/themes/github.com/davegallant/hugo-theme-gruvbox/.eslintignore new file mode 100644 index 00000000..fb0c63f4 --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.eslintignore @@ -0,0 +1,5 @@ +assets/js/flexsearch.js +assets/js/prism.js + +public +resources \ No newline at end of file diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.eslintrc.json b/themes/github.com/davegallant/hugo-theme-gruvbox/.eslintrc.json new file mode 100644 index 00000000..b151c336 --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.eslintrc.json @@ -0,0 +1,14 @@ +{ + "env": { + "browser": true, + "es6": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:prettier/recommended" + ], + "parserOptions": { + "sourceType": "module" + } +} \ No newline at end of file diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.github/renovate.json b/themes/github.com/davegallant/hugo-theme-gruvbox/.github/renovate.json new file mode 100644 index 00000000..8a256bcc --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.github/renovate.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:base"], + "rebaseWhen": "behind-base-branch", + "npm": { + "fileMatch": ["(^|/)package\\.hugo\\.json$"], + "rangeStrategy": "bump", + "updateLockFiles": false, + "ignoreTests": true, + "ignorePaths": [ + "package.json", + + "**/node_modules/**", + "**/bower_components/**", + "**/vendor/**", + "**/examples/**", + "**/__tests__/**", + "**/test/**", + "**/tests/**", + "**/__fixtures__/**" + ] + }, + "gomod": { + "fileMatch": ["(^|/)go\\.mod$"], + "rangeStrategy": "bump" + }, + "packageRules": [ + { + "matchManagers": ["gomod"], + "matchDepTypes": ["indirect"], + "enabled": true, + "groupName": "Hugo Modules" + }, + { + "extends": "packages:linters", + "groupName": "linters" + }, + { + "extends": "packages:postcss", + "groupName": "postcss packages" + } + ] +} diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.github/workflows/publish.yml b/themes/github.com/davegallant/hugo-theme-gruvbox/.github/workflows/publish.yml new file mode 100644 index 00000000..d536204b --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.github/workflows/publish.yml @@ -0,0 +1,84 @@ +name: Publish Hugo Site + +on: + push: + branches: + - main + +jobs: + update_hugo_npm_dependencies: + name: Update Hugo npm Dependencies + runs-on: ubuntu-latest + permissions: + contents: write + outputs: + commit_hash: ${{ steps.commit_changes.outputs.commit_hash }} + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: "18" + + - name: Install Hugo + uses: peaceiris/actions-hugo@v2 + with: + hugo-version: "0.111.3" + extended: true + + - name: Write composite package.json + run: hugo mod npm pack + + - name: Install npm Packages + run: npm install + + - name: Display Changes + run: git status + + - name: Commit Changes + id: commit_changes + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: Update Hugo npm Dependencies + + publish: + name: Publish Hugo Site + needs: update_hugo_npm_dependencies + runs-on: ubuntu-latest + permissions: + contents: read + deployments: write + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod + ref: ${{ needs.update_hugo_npm_dependencies.outputs.commit_hash }} + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: "18" + + - name: Install Hugo + uses: peaceiris/actions-hugo@v2 + with: + hugo-version: "0.111.3" + extended: true + + - name: Install npm Packages + run: npm ci + + - name: Build Hugo + run: hugo --minify + + - name: Deploy to Cloudflare Pages + uses: cloudflare/pages-action@v1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + projectName: hugo-theme-gruvbox + directory: ./public + gitHubToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.github/workflows/renovate-hugo-modules.yml b/themes/github.com/davegallant/hugo-theme-gruvbox/.github/workflows/renovate-hugo-modules.yml new file mode 100644 index 00000000..d8423050 --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.github/workflows/renovate-hugo-modules.yml @@ -0,0 +1,35 @@ +name: Renovate Hugo Modules + +on: pull_request + +jobs: + renovate_hugo_modules: + name: Renovate Hugo Modules + if: startsWith(github.head_ref, 'renovate/hugo-modules') + runs-on: ubuntu-latest + steps: + - name: Checkout Pull Request HEAD Commit + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Install Hugo + uses: peaceiris/actions-hugo@v2 + with: + hugo-version: "0.111.3" + extended: true + + - name: Update All Hugo Modules + run: hugo mod get -u + + - name: Tidy Hugo Modules + run: hugo mod tidy + + - name: Display Changes + run: git status + + - name: Commit Changes + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: Renovate Hugo Modules + commit_author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.gitignore b/themes/github.com/davegallant/hugo-theme-gruvbox/.gitignore new file mode 100644 index 00000000..cb2c1016 --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.gitignore @@ -0,0 +1,159 @@ +# Created by https://www.toptal.com/developers/gitignore/api/hugo,node +# Edit at https://www.toptal.com/developers/gitignore?templates=hugo,node + +### Hugo ### +# Generated files by hugo +/public/ +/resources/_gen/ +/assets/jsconfig.json +hugo_stats.json + +# Executable may be added to repository +hugo.exe +hugo.darwin +hugo.linux + +# Temporary lock file while building +/.hugo_build.lock + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +# End of https://www.toptal.com/developers/gitignore/api/hugo,node diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.husky/.gitignore b/themes/github.com/davegallant/hugo-theme-gruvbox/.husky/.gitignore new file mode 100644 index 00000000..31354ec1 --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.husky/.gitignore @@ -0,0 +1 @@ +_ diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.husky/pre-commit b/themes/github.com/davegallant/hugo-theme-gruvbox/.husky/pre-commit new file mode 100644 index 00000000..a16d8b1d --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname "$0")/_/husky.sh" + +npx lint-staged diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.markdownlintignore b/themes/github.com/davegallant/hugo-theme-gruvbox/.markdownlintignore new file mode 100644 index 00000000..16608a0e --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.markdownlintignore @@ -0,0 +1,11 @@ +node_modules + +public +resources + +# Leave content from gohugoio/hugoBasicExample as is +content/blog/emoji-support.md +content/blog/markdown-syntax.md +content/blog/math-typesetting.md +content/blog/placeholder-text.md +content/blog/rich-content.md \ No newline at end of file diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.prettierignore b/themes/github.com/davegallant/hugo-theme-gruvbox/.prettierignore new file mode 100644 index 00000000..cb390dc3 --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.prettierignore @@ -0,0 +1,4 @@ +assets/css/critical/15-colors.css +assets/css/non-critical/00-vendor.css +assets/js/flexsearch.js +assets/js/prism.js \ No newline at end of file diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.prettierrc.json b/themes/github.com/davegallant/hugo-theme-gruvbox/.prettierrc.json new file mode 100644 index 00000000..025b3612 --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.prettierrc.json @@ -0,0 +1,12 @@ +{ + "plugins": ["prettier-plugin-go-template"], + "proseWrap": "always", + "overrides": [ + { + "files": ["*.html"], + "options": { + "parser": "go-template" + } + } + ] +} diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.stylelintignore b/themes/github.com/davegallant/hugo-theme-gruvbox/.stylelintignore new file mode 100644 index 00000000..2da6412c --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.stylelintignore @@ -0,0 +1,5 @@ +assets/css/critical/15-colors.css +assets/css/non-critical/00-vendor.css + +public +resources \ No newline at end of file diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/.stylelintrc.json b/themes/github.com/davegallant/hugo-theme-gruvbox/.stylelintrc.json new file mode 100644 index 00000000..df7e01b1 --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/.stylelintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["stylelint-prettier/recommended"] +} diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/LICENSE b/themes/github.com/davegallant/hugo-theme-gruvbox/LICENSE new file mode 100644 index 00000000..a03b73d7 --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Michael Schnerring + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/themes/github.com/davegallant/hugo-theme-gruvbox/README.md b/themes/github.com/davegallant/hugo-theme-gruvbox/README.md new file mode 100644 index 00000000..797674b2 --- /dev/null +++ b/themes/github.com/davegallant/hugo-theme-gruvbox/README.md @@ -0,0 +1,577 @@ +# Gruvbox Hugo Theme + +A retro-looking [Hugo](https://gohugo.io/) theme inspired by +[gruvbox](https://github.com/morhetz/gruvbox) to build secure, fast, and +SEO-ready websites. + +This theme is easily customizable with features that any coder loves. + +I took a lot of inspiration from the +[Hello Friend](https://github.com/panr/hugo-theme-hello-friend) and +[Doks](https://github.com/h-enk/doks) Hugo themes. + +## DEMO [https://hugo-theme-gruvbox.schnerring.net/](https://hugo-theme-gruvbox.schnerring.net/) + +![Screenshot of the theme in dark and light colors](https://raw.githubusercontent.com/schnerring/hugo-theme-gruvbox/main/images/tn.png) + +## DISCLAIMER: Project Status + +This theme is still in early development. +[Check out the issues](https://github.com/schnerring/hugo-theme-gruvbox/issues) +to see what's still missing. + +## Highlights + +- [Code highlighting with Prism](#prism) +- Full-text search with [Flex Search](https://github.com/nextapps-de/flexsearch) +- Display your CV using structured [JSON Resume](https://jsonresume.org/) data +- [Integrated image optimization with next-gen image formats and lazy loading](#image-optimization) +- Dark mode that also changes Prism themes +- [Dynamic color choices from the Gruvbox color palette](#colors) +- [Extensible to make it suit your needs](#extensibility) +- Responsive, mobile-first design +- Beautiful SVG icons with [Tabler Icons](https://tabler-icons.io/) + +A big thank you to the authors of the software that make this theme possible! ❤️ + +## Quickstart + +The theme requires _extended_ Hugo because it uses Sass/SCSS. You'll also have +to install Go because the theme uses Go modules. + +1. `git clone` the repository and `cd` into it +2. Run `npm ci` to install the dependencies +3. Run `hugo server` + +## Install The Theme + +Create a new Hugo website: + +```shell +hugo new site example.com +cd example.com/ +``` + +Initialize the site as Hugo module + +```shell +hugo mod init example.com +``` + +Add the following to the `config.toml` file: + +```toml +[markup] + # (Optional) To be able to use all Prism plugins, the theme enables unsafe + # rendering by default + #_merge = "deep" + +[build] + # The theme enables writeStats which is required for PurgeCSS + _merge = "deep" + +# This hopefully will be simpler in the future. +# See: https://github.com/schnerring/hugo-theme-gruvbox/issues/16 +[module] + [[module.imports]] + path = "github.com/schnerring/hugo-theme-gruvbox" + [[module.imports]] + path = "github.com/schnerring/hugo-mod-json-resume" + [[module.imports.mounts]] + source = "data" + target = "data" + [[module.imports.mounts]] + source = "layouts" + target = "layouts" + [[module.imports.mounts]] + source = "assets/css/json-resume.css" + target = "assets/css/critical/44-json-resume.css" + [[module.mounts]] + # required by hugo-mod-json-resume + source = "node_modules/simple-icons/icons" + target = "assets/simple-icons" + [[module.mounts]] + source = "assets" + target = "assets" + [[module.mounts]] + source = "layouts" + target = "layouts" + [[module.mounts]] + source = "static" + target = "static" + [[module.mounts]] + source = "node_modules/prismjs" + target = "assets/prismjs" + [[module.mounts]] + source = "node_modules/prism-themes/themes" + target = "assets/prism-themes" + [[module.mounts]] + source = "node_modules/typeface-fira-code/files" + target = "static/fonts" + [[module.mounts]] + source = "node_modules/typeface-roboto-slab/files" + target = "static/fonts" + [[module.mounts]] + source = "node_modules/@tabler/icons/icons" + target = "assets/tabler-icons" +``` + +Install the theme: + +```shell +hugo mod get +``` + +Initialize the NPM `package.json` and install the dependencies: + +```shell +hugo mod npm pack +npm install +``` + +Run Hugo: + +```shell +hugo server +``` + +## Update The Theme + +Update the Hugo modules: + +```shell +hugo mod get -u +hugo mod tidy +``` + +Update the NPM dependencies: + +```shell +hugo mod npm pack +npm install +``` + +## Colors + +Two options are available to configure the theme colors: + +- `defaultTheme`: `dark` or `light` (defaults to `light`) + Default theme color for when a user visits the site for the first time. OS or + user preference override this setting. + [See this comment for more details.](https://github.com/schnerring/hugo-theme-gruvbox/issues/34#issuecomment-1235870375) +- `themeColor`: `gray`, `red`, `green`, `yellow`, `blue`, `purple`, `aqua`, or + `orange` (defaults to `blue`) + Theme color for things such as links, headings etc. +- `themeContrast`: `soft`, `medium`, or `hard` (defaults to `medium`) + Theme background color + +## Prism + +The theme allows customization of [Prism](https://prismjs.com/) via +`config.toml` parameters: + +```toml +[params] + [params.prism] + languages = [ + "markup", + "css", + "clike", + "javascript" + ] + plugins = [ + "normalize-whitespace", + "toolbar", + "copy-to-clipboard" + ] +``` + +In my opinion, this is the coolest feature of the theme. Other Hugo themes +usually include a pre-configured version of Prism, which complicates updates and +change tracking, and clutters the theme's code base with third-party JavaScript. + +The Prism theme is not configurable because of the integration with the dark +mode functionality. Toggling between color modes swaps the Prism theme between +[`gruvbox-dark`](https://github.com/PrismJS/prism-themes/blob/master/themes/prism-gruvbox-dark.css) +and +[`gruvbox-light`](https://github.com/PrismJS/prism-themes/blob/master/themes/prism-gruvbox-light.css) +from [github.com/PrismJS/prism-themes](https://github.com/PrismJS/prism-themes). + +Check out the +[Prism showcase on the Demo site for examples](https://hugo-theme-gruvbox.schnerring.net/blog/prism-code-highlighting-showcase/) + +### Explore Prism Features + +After running `npm install`, explore Prism features like this: + +```shell +# Languages +ls node_modules/prismjs/components + +# Plugins +ls node_modules/prismjs/plugins +``` + +## Image Optimization + +Images are optimized by default without requiring +[shortcodes](https://gohugo.io/content-management/shortcodes/). A +[custom render hook](https://gohugo.io/getting-started/configuration-markup#markdown-render-hooks) +does all the heavy lifting (see +[render-image.html](./layouts/_default/_markup/render-image.html)). + +By default, the theme creates resized versions of images ranging from 300 to 700 +pixels wide in increments of 100 pixels. + +If the image format is not [WebP](https://en.wikipedia.org/wiki/WebP), the image +is converted. The original file format will serve as a fallback for browsers +that don't support the WebP format. + +Note that only images that are part of the +[page bundle](https://gohugo.io/content-management/page-bundles/) are processed. +If served from the `static/` directory or external sources, the image will be +displayed but not be processed. + +Additionally, all images are lazily loaded to save the bandwidth of your users. + +### Configuration + +The default quality is 75%. See the +[official Image Processing Config Hugo docs](https://gohugo.io/content-management/image-processing/#image-processing-config). +Change it by adding the following to the `config.toml` file: + +```toml +[imaging] + quality = 75 +``` + +Change the resize behavior: + +```toml +[params] + [params.imageResize] + min = 300 + max = 700 + increment = 100 +``` + +### Captions + +```markdown +![Alt text](image-url.jpg "Caption with **markdown support**") +``` + +[The demo site features examples you can look at](https://hugo-theme-gruvbox.schnerring.net/blog/image-optimization/). +I also use the theme for [my website](https://schnerring.net). + +### Blog Post Covers + +Add blog post covers by defining them in the +[front matter](https://gohugo.io/content-management/front-matter/) of your +posts: + +```markdown +--- +cover: + src: my-blog-cover.jpg + alt: A beautiful image containing interesting things + caption: [Source](https://www.flickr.com/) +--- +``` + +## Embed Video Files + +Use the +[video shortcode](https://github.com/schnerring/hugo-theme-gruvbox/blob/main/layouts/shortcodes/video.html) +to embed your video files from +[Page Resources](https://gohugo.io/content-management/page-resources/). + +With a page bundle looking like the following: + +```text +embed-videos/ +|-- index.md +|-- my-video.jpg +|-- my-video.mp4 +|-- my-video.webm +``` + +You can embed `my-video` like this: + +```markdown +{{< video src="my-video" autoplay="true" controls="false" loop="true" >}} +``` + +The shortcode looks for media files matching the filename `my-video*`. For each +`video` MIME type file, a `` element is added. The first `image` MIME +type file is used as `poster` (thumbnail). It will render the following HTML: + +```html + +``` + +You can set a Markdown `caption`, wrapping the `