Repository: thegeeklab/hugo-geekdoc Branch: main Commit: f0794c7aadbe Files: 206 Total size: 267.4 KB Directory structure: gitextract_qte0gx_s/ ├── .cspell.json ├── .github/ │ └── settings.yaml ├── .gitignore ├── .gitsv/ │ └── config.yaml ├── .htmlvalidate.json ├── .jsbeautifyrc ├── .lighthouserc.yaml ├── .lycheeignore ├── .markdownlint.yaml ├── .npmrc ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── .tarignore ├── .woodpecker/ │ ├── build-package.yaml │ ├── docs.yaml │ └── static.yaml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── archetypes/ │ ├── docs.md │ └── posts.md ├── assets/ │ └── search/ │ ├── config.json │ └── data.json ├── eslint.config.js ├── exampleSite/ │ ├── config/ │ │ └── _default/ │ │ ├── hugo.yaml │ │ ├── languages.yaml │ │ └── params.yaml │ ├── content/ │ │ └── en/ │ │ ├── _includes/ │ │ │ ├── _index.md │ │ │ └── include-page.md │ │ ├── _index.md │ │ ├── asciidoc/ │ │ │ ├── admonition-icons.adoc │ │ │ └── admonitions.adoc │ │ ├── collapse/ │ │ │ ├── _index.md │ │ │ ├── level-1/ │ │ │ │ ├── _index.md │ │ │ │ ├── level-1-1.md │ │ │ │ └── level-1-2.md │ │ │ └── level-2/ │ │ │ ├── _index.md │ │ │ ├── level-2-1.md │ │ │ └── level-2-2.md │ │ ├── features/ │ │ │ ├── _index.md │ │ │ ├── code-blocks.md │ │ │ ├── dark-mode/ │ │ │ │ └── _index.md │ │ │ ├── icon-sets.md │ │ │ ├── multilingual/ │ │ │ │ └── _index.md │ │ │ └── theming/ │ │ │ └── _index.md │ │ ├── posts/ │ │ │ ├── _index.md │ │ │ ├── hello_geekdoc.md │ │ │ └── initial-release.md │ │ ├── shortcodes/ │ │ │ ├── _index.md │ │ │ ├── audio/ │ │ │ │ └── _index.md │ │ │ ├── avatar/ │ │ │ │ └── _index.md │ │ │ ├── buttons.md │ │ │ ├── columns.md │ │ │ ├── expand.md │ │ │ ├── hints.md │ │ │ ├── icons.md │ │ │ ├── images/ │ │ │ │ └── _index.md │ │ │ ├── includes.md │ │ │ ├── katex.md │ │ │ ├── mermaid.md │ │ │ ├── progress.md │ │ │ ├── propertylist.md │ │ │ ├── tabs.md │ │ │ ├── toc-tree.md │ │ │ └── toc.md │ │ ├── toc-tree/ │ │ │ ├── _index.md │ │ │ ├── level-1/ │ │ │ │ ├── _index.md │ │ │ │ ├── level-1-1.md │ │ │ │ ├── level-1-2.md │ │ │ │ └── level-1-3/ │ │ │ │ ├── _index.md │ │ │ │ └── level-1-3-1.md │ │ │ └── level-2/ │ │ │ ├── _index.md │ │ │ ├── level-2-1.md │ │ │ └── level-2-2.md │ │ └── usage/ │ │ ├── _index.md │ │ ├── configuration.md │ │ ├── customization.md │ │ ├── getting-started.md │ │ └── menus.md │ ├── data/ │ │ ├── menu/ │ │ │ ├── extra.yaml │ │ │ ├── main.yaml │ │ │ └── more.yaml │ │ └── properties/ │ │ ├── demo.yaml │ │ ├── shortcode-audio.yaml │ │ ├── shortcode-avatar.yaml │ │ ├── shortcode-buttons.yaml │ │ ├── shortcode-columns.yaml │ │ ├── shortcode-hints.yaml │ │ ├── shortcode-images.yaml │ │ ├── shortcode-includes.yaml │ │ ├── shortcode-katex.yaml │ │ ├── shortcode-mermaid.yaml │ │ ├── shortcode-progress.yaml │ │ ├── shortcode-propertylist.yaml │ │ ├── shortcode-toc-tree.yaml │ │ └── shortcode-toc.yaml │ ├── layouts/ │ │ └── shortcodes/ │ │ └── sprites.html │ └── static/ │ ├── .htaccess │ ├── _includes/ │ │ ├── example.html.part │ │ └── example.md.part │ ├── custom.css │ └── custom.css.example ├── i18n/ │ ├── am.yaml │ ├── cs.yaml │ ├── da.yaml │ ├── de.yaml │ ├── en.yaml │ ├── es.yaml │ ├── fr.yaml │ ├── it.yaml │ ├── ja.yaml │ ├── nl.yaml │ ├── oc.yaml │ └── zh-cn.yaml ├── layouts/ │ ├── 404.html │ ├── _default/ │ │ ├── _markup/ │ │ │ ├── render-codeblock-mermaid.html │ │ │ ├── render-heading.html │ │ │ ├── render-image.html │ │ │ └── render-link.html │ │ ├── baseof.html │ │ ├── list.html │ │ ├── single.html │ │ ├── taxonomy.html │ │ └── terms.html │ ├── partials/ │ │ ├── foot.html │ │ ├── head/ │ │ │ ├── custom.html │ │ │ ├── favicons.html │ │ │ ├── meta.html │ │ │ ├── microformats.html │ │ │ ├── others.html │ │ │ └── rel-me.html │ │ ├── language.html │ │ ├── menu-bundle-np.html │ │ ├── menu-bundle.html │ │ ├── menu-extra.html │ │ ├── menu-filetree-np.html │ │ ├── menu-filetree.html │ │ ├── menu.html │ │ ├── microformats/ │ │ │ ├── opengraph.html │ │ │ ├── schema.html │ │ │ └── twitter_cards.html │ │ ├── page-header.html │ │ ├── page-metadata.html │ │ ├── pagination.html │ │ ├── posts/ │ │ │ └── metadata.html │ │ ├── search.html │ │ ├── site-footer.html │ │ ├── site-header.html │ │ ├── svg-icon-symbols.html │ │ └── utils/ │ │ ├── content.html │ │ ├── description.html │ │ ├── featured.html │ │ └── title.html │ ├── posts/ │ │ ├── list.html │ │ └── single.html │ ├── robots.txt │ └── shortcodes/ │ ├── audio.html │ ├── avatar.html │ ├── button.html │ ├── columns.html │ ├── expand.html │ ├── gist.html │ ├── hint.html │ ├── icon.html │ ├── img.html │ ├── include.html │ ├── katex.html │ ├── mermaid.html │ ├── progress.html │ ├── propertylist.html │ ├── tab.html │ ├── tabs.html │ ├── toc-tree.html │ └── toc.html ├── package.json ├── renovate.json ├── src/ │ ├── js/ │ │ ├── accessibility.js │ │ ├── colorTheme.js │ │ ├── config.js │ │ ├── index.js │ │ ├── katex.js │ │ ├── mermaid.js │ │ └── search.js │ ├── sass/ │ │ ├── _asciidoc.scss │ │ ├── _base.scss │ │ ├── _chroma_base.scss │ │ ├── _chroma_dark.scss │ │ ├── _chroma_light.scss │ │ ├── _color_mode.scss │ │ ├── _defaults.scss │ │ ├── _fonts.scss │ │ ├── _markdown.scss │ │ ├── _mobile.scss │ │ ├── _normalize.css │ │ ├── _print.scss │ │ ├── _shortcodes.scss │ │ ├── _utils.scss │ │ ├── main.scss │ │ ├── mobile.scss │ │ └── print.scss │ └── static/ │ └── custom.css ├── svgsprite.config.json ├── theme.toml ├── webpack.config.js └── webpack.plugins.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .cspell.json ================================================ { "version": "0.2", "language": "en", "dictionaries": ["en_us", "softwareTerms", "companies", "bash", "html", "css", "typescript"], "words": [ "geekdoc", "katex", "flexsearch", "pygments", "Geekdocs", "goldmark", "THEMEDIR", "gohugo", "canonify", "codecopy", "lstore", "lntable", "lastmod", "Preproc", "lntd", "Emph", "anchorwrap", "languagecode", "relref", "linenos", "admonitionblock", "uuidv4", "cfworker", "readmore", "editpage", "codecontainer", "necolas", "Shpak", "Kaussow" ], "ignorePaths": [ ".woodpecker", ".cspell.json", ".git", ".gitignore", ".vscode", "*.svg", "renovate.json", "package.json", ".lighthouserc.yaml", "config.yaml", "hugo.yaml", "webpack.config.js", "theme.toml", "svgsprite.config.json", "i18n/*" ], "ignoreRegExpList": ["&\\S+;", "{{.+}}"] } ================================================ FILE: .github/settings.yaml ================================================ repository: name: hugo-geekdoc description: Hugo theme made for documentation homepage: https://geekdocs.de topics: hugo, theme, hugo-theme, documentation private: false has_issues: true has_projects: false has_wiki: false has_downloads: true default_branch: main allow_squash_merge: true allow_merge_commit: true allow_rebase_merge: true labels: - name: bug color: d73a4a description: Something isn't working - name: documentation color: 0075ca description: Improvements or additions to documentation - name: duplicate color: cfd3d7 description: This issue or pull request already exists - name: enhancement color: a2eeef description: New feature or request - name: good first issue color: 7057ff description: Good for newcomers - name: help wanted color: 008672 description: Extra attention is needed - name: invalid color: e4e669 description: This doesn't seem right - name: question color: d876e3 description: Further information is requested - name: wontfix color: ffffff description: This will not be worked on branches: - name: main protection: required_pull_request_reviews: null required_status_checks: strict: false contexts: - ci/woodpecker/pr/static - ci/woodpecker/pr/build-package - ci/woodpecker/pr/docs enforce_admins: false required_linear_history: true restrictions: null ================================================ FILE: .gitignore ================================================ # local environments .swp .env* /dist/ /build/ /node_modules/ /lhci_reports/ /exampleSite/themes/ /exampleSite/public/ /exampleSite/config/development/ CHANGELOG.md VERSION # translation envs exampleSite/content/de # auto-generated files /data/ /static/ /assets/sprites/ /resources/ /exampleSite/resources/ /exampleSite/data/sprites/ VERSION # hugo .hugo_build.lock # testing .lighthouseci/ ================================================ FILE: .gitsv/config.yaml ================================================ --- version: "1.1" versioning: update-major: [] update-minor: [feat] update-patch: [fix, perf, refactor, chore, test, ci, docs] tag: pattern: "v%d.%d.%d" release-notes: sections: - name: Features commit-types: [feat] section-type: commits - name: Bug Fixes commit-types: [fix] section-type: commits - name: Performance Improvements commit-types: [perf] section-type: commits - name: Code Refactoring commit-types: [refactor] section-type: commits - name: Others commit-types: [chore] section-type: commits - name: Testing commit-types: [test] section-type: commits - name: CI Pipeline commit-types: [ci] section-type: commits - name: Documentation commit-types: [docs] section-type: commits - name: BREAKING CHANGES section-type: breaking-changes commit-message: footer: issue: key: issue add-value-prefix: "#" issue: regex: "#?[0-9]+" ================================================ FILE: .htmlvalidate.json ================================================ { "extends": ["html-validate:standard"], "rules": { "element-required-content": "off", "element-permitted-content": "off", "no-raw-characters": "off", "attribute-misuse": "warn" } } ================================================ FILE: .jsbeautifyrc ================================================ { "indent_size": 4, "indent_char": " ", "preserve_newlines": false, "unformatted": ["svg"], "content_unformatted": ["pre"], "extra_liners": ["head", "body", "html", "main", "header", "footer", "section"] } ================================================ FILE: .lighthouserc.yaml ================================================ --- ci: collect: numberOfRuns: 3 staticDistDir: exampleSite/public url: - http://localhost/ - http://localhost/404.html - http://localhost/usage/getting-started/ settings: chromeFlags: "--no-sandbox --headless --disable-dev-shm-usage" onlyCategories: ["performance", "accessibility", "best-practices", "seo"] skipAudits: [ "color-contrast", "uses-long-cache-ttl", "csp-xss", "bf-cache", "is-crawlable", "image-size-responsive", "render-blocking-resources", "largest-contentful-paint", "unused-css-rules", "network-dependency-tree-insight", "legacy-javascript", "errors-in-console", "max-potential-fid", "interactive", "dom-size", "forced-reflow-insight", "unused-javascript", "cls-culprits-insight", "cache-insight", "render-blocking-insight" ] assert: preset: "lighthouse:no-pwa" assertions: color-contrast: off uses-long-cache-ttl: off csp-xss: off # FIXME: https://github.com/GoogleChrome/lighthouse/issues/14957 bf-cache: off is-crawlable: off image-size-responsive: off render-blocking-resources: off largest-contentful-paint: off unused-css-rules: off network-dependency-tree-insight: off cls-culprits-insight: off cache-insight: off render-blocking-insight: off legacy-javascript: off errors-in-console: off max-potential-fid: off interactive: off dom-size: off forced-reflow-insight: off unused-javascript: off total-byte-weight: warn identical-links-same-purpose: warn tap-targets: off unsized-images: warn # FIXME: https://github.com/GoogleChrome/lighthouse/issues/11460 categories:performance: - warn - minScore: 0.95 categories:accessibility: - error - minScore: 1 categories:seo: - error - minScore: 0.95 upload: target: filesystem outputDir: lhci_reports ================================================ FILE: .lycheeignore ================================================ https://github.com/thegeeklab/.+/edit/main/.* https://unsplash.com.* https://www.color-hex.com.* https://geekdocs.de/ ================================================ FILE: .markdownlint.yaml ================================================ --- default: True MD013: False MD041: False MD042: False MD004: style: dash MD010: code_blocks: False ================================================ FILE: .npmrc ================================================ loglevel=error fund=false engine-strict=true ================================================ FILE: .nvmrc ================================================ lts/* ================================================ FILE: .prettierignore ================================================ _normalize.css list.json.json /.lighthouseci/ /themes/ /static/js/ /src/favicon/ LICENSE **/*.html ================================================ FILE: .prettierrc ================================================ { "printWidth": 99, "singleQuote": false, "semi": false, "trailingComma": "none" } ================================================ FILE: .tarignore ================================================ .envrc .nvmrc .npmrc .tarignore .git* .woodpecker* .lighthouse* .markdownlint* .jsbeautify* .prettier* .htmlvalidate* .lycheeignore* .cspell* eslint* example* webpack* svgsprite* package* node* local* dist src build renovate* resources CONTRIBUTING.md ================================================ FILE: .woodpecker/build-package.yaml ================================================ --- when: - event: [pull_request, tag] - event: [push, manual] branch: - ${CI_REPO_DEFAULT_BRANCH} steps: - name: assets image: docker.io/library/node:lts commands: - npm install --quiet --no-progress - npm run build - cat VERSION environment: FORCE_COLOR: "true" - name: package image: docker.io/library/node:lts commands: - npm run pack environment: FORCE_COLOR: "true" - name: checksum image: quay.io/thegeeklab/alpine-tools commands: - cd dist/ && sha256sum * > ../sha256sum.txt - name: changelog image: quay.io/thegeeklab/git-sv commands: - git sv current-version - git sv release-notes -t ${CI_COMMIT_TAG:-next} -o CHANGELOG.md - cat CHANGELOG.md - name: publish-github image: docker.io/plugins/github-release settings: api_key: from_secret: github_token files: - dist/* - sha256sum.txt note: CHANGELOG.md overwrite: true title: ${CI_COMMIT_TAG} when: - event: [tag] depends_on: - static ================================================ FILE: .woodpecker/docs.yaml ================================================ --- when: - event: [pull_request, tag] - event: [push, manual] branch: - ${CI_REPO_DEFAULT_BRANCH} steps: - name: assets image: docker.io/library/node:lts commands: - npm install --quiet --no-progress - npm run svg-sprite-list - mkdir -p exampleSite/themes/${CI_REPO_NAME} - curl -sSL https://github.com/${CI_REPO}/releases/latest/download/${CI_REPO_NAME}.tar.gz | tar -xz -C exampleSite/themes/${CI_REPO_NAME}/ --strip-components=1 when: - event: [tag] - event: [push, manual] branch: - ${CI_REPO_DEFAULT_BRANCH} - name: assets-main image: docker.io/library/node:lts commands: - npm install --quiet --no-progress - npm run build - npm run svg-sprite-list - mkdir -p exampleSite/themes/ && ln -s $(pwd)/ exampleSite/themes/${CI_REPO_NAME} environment: FORCE_COLOR: "true" when: - event: [pull_request] - name: build image: quay.io/thegeeklab/hugo:0.160 commands: - hugo --panicOnWarning -s exampleSite/ - name: beautify image: quay.io/thegeeklab/alpine-tools commands: - html-beautify -r -f 'exampleSite/public/**/*.html' environment: FORCE_COLOR: "true" - name: publish image: quay.io/thegeeklab/wp-s3-action settings: access_key: from_secret: s3_access_key bucket: geekdocs-root delete: true endpoint: from_secret: s3_endpoint path_style: true secret_key: from_secret: s3_secret_access_key source: exampleSite/public/ strip_prefix: exampleSite/public/ when: - event: [tag] - event: [push, manual] branch: - ${CI_REPO_DEFAULT_BRANCH} status: [success, failure] depends_on: - build-package ================================================ FILE: .woodpecker/static.yaml ================================================ --- when: - event: [pull_request, tag] - event: [push, manual] branch: - ${CI_REPO_DEFAULT_BRANCH} steps: - name: eslint image: docker.io/library/node:lts depends_on: [] commands: - npm install --quiet --no-progress - npm run lint:js environment: FORCE_COLOR: "true" - name: markdownlint image: quay.io/thegeeklab/markdownlint-cli depends_on: [] commands: - markdownlint 'exampleSite/content/**/*.md' 'README.md' 'CONTRIBUTING.md' - name: spellcheck image: ghcr.io/streetsidesoftware/cspell depends_on: [] commands: - cspell-cli lint . --gitignore --color - name: assets image: docker.io/library/node:lts depends_on: [] commands: - npm install --quiet --no-progress - npm run build environment: FORCE_COLOR: "true" - name: testbuild image: quay.io/thegeeklab/hugo:0.160 depends_on: [assets] commands: - mkdir -p exampleSite/themes/ && ln -s $(pwd)/ exampleSite/themes/${CI_REPO_NAME} - hugo --panicOnWarning -s exampleSite/ - name: link-validation image: docker.io/lycheeverse/lychee:0.23 depends_on: [testbuild] commands: - lychee --no-progress --format detailed README.md - lychee --no-progress --format detailed --root-dir "$(pwd)/exampleSite/public" "exampleSite/public/**/*.html" environment: GITHUB_TOKEN: from_secret: github_token_ro - name: html-validation image: docker.io/library/node:lts depends_on: [testbuild] commands: - npm install --quiet --no-progress - npm run lint:html environment: FORCE_COLOR: "true" - name: page-validation image: quay.io/thegeeklab/lhci:0.15 depends_on: [testbuild] commands: - lhci autorun environment: LHCI_SERVER_URL: https://ci-artifact.rknet.org/${CI_REPO_NAME}/ ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing ## Security If you think you have found a **security issue**, please do not mention it in this repository. Instead, send an email to `security@thegeeklab.de` with as many details as possible so it can be handled confidential. ## Bug Reports and Feature Requests If you have found a **bug** or have a **feature request** please use the search first to see if a similar issue already exists. If not, please create an issue in this repository ## Code If you would like to fix a bug or implement a feature, please fork the repository and create a Pull Request. Before you start any Pull Request, it is recommended that you create an issue to discuss first if you have any doubts about requirement or implementation. That way you can be sure that the maintainer(s) agree on what to change and how, and you can hopefully get a quick merge afterwards. Pull Requests can only be merged once all status checks are green. ## Do not force push to your Pull Request branch Please do not force push to your Pull Requests branch after you have created your Pull Request, as doing so makes it harder for us to review your work. Pull Requests will always be squashed by us when we merge your work. Commit as many times as you need in your Pull Request branch. ## Re-requesting a review Please do not ping your reviewer(s) by mentioning them in a new comment. Instead, use the re-request review functionality. Read more about this in the [GitHub docs, Re-requesting a review](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request#re-requesting-a-review). ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2022 Robert Kaussow 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 (including the next paragraph) 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. ================================================ FILE: README.md ================================================ # Geekdoc [![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/hugo-geekdoc/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/hugo-geekdoc) [![Hugo Version](https://img.shields.io/badge/hugo-0.156-blue.svg)](https://gohugo.io) [![GitHub release](https://img.shields.io/github/v/release/thegeeklab/hugo-geekdoc)](https://github.com/thegeeklab/hugo-geekdoc/releases/latest) [![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/hugo-geekdoc)](https://github.com/thegeeklab/hugo-geekdoc/graphs/contributors) [![License: MIT](https://img.shields.io/github/license/thegeeklab/hugo-geekdoc)](https://github.com/thegeeklab/hugo-geekdoc/blob/main/LICENSE) Geekdoc is a simple Hugo theme for documentations. It is intentionally designed as a fast and lean theme and may not fit the requirements of complex projects. If a more feature-complete theme is required there are a lot of great alternatives out there. You can find a demo and the full documentation at [https://geekdocs.de](https://geekdocs.de). ![Desktop and mobile preview](https://raw.githubusercontent.com/thegeeklab/hugo-geekdoc/main/images/readme.png) ## Build and release process This theme is subject to a CI driven build and release process common for software development. During the release build, all necessary assets are automatically built by [webpack](https://webpack.js.org/) and bundled in a release tarball. You can download the latest release from the GitHub [release page](https://github.com/thegeeklab/hugo-geekdoc/releases). Due to the fact that `webpack` and `npm scripts` are used as pre-processors, the theme cannot be used from the main branch by default. If you want to use the theme from a cloned branch instead of a release tarball you'll need to install `webpack` locally and run the build script once to create all required assets. ```shell # install required packages from package.json npm install # run the build script to build required assets npm run build # build release tarball npm run pack ``` See the [Getting Started Guide](https://geekdocs.de/usage/getting-started/) for details about the different setup options. ## Contributors Special thanks to all [contributors](https://github.com/thegeeklab/hugo-geekdoc/graphs/contributors). If you would like to contribute, please see the [instructions](https://github.com/thegeeklab/hugo-geekdoc/blob/main/CONTRIBUTING.md). Geekdoc is inspired and partially based on the [hugo-book](https://github.com/alex-shpak/hugo-book) theme, thanks [Alex Shpak](https://github.com/alex-shpak/) for your work. ## License This project is licensed under the MIT License - see the [LICENSE](https://github.com/thegeeklab/hugo-geekdoc/blob/main/LICENSE) file for details. The used SVG icons and generated icon fonts are licensed under the license of the respective icon pack: - Font Awesome: [CC BY 4.0 License](https://github.com/FortAwesome/Font-Awesome#license) - IcoMoon Free Pack: [GPL/CC BY 4.0](https://icomoon.io/#icons-icomoon) - Material Icons: [Apache License 2.0](https://github.com/google/material-design-icons/blob/main/LICENSE) ================================================ FILE: archetypes/docs.md ================================================ --- title: "{{ .Name | humanize | title }}" weight: 1 # geekdocFlatSection: false # geekdocToc: 6 # geekdocHidden: false --- ================================================ FILE: archetypes/posts.md ================================================ --- title: "{{ replace .Name "-" " " | title }}" date: {{ .Date }} --- ================================================ FILE: assets/search/config.json ================================================ {{- $searchDataFile := printf "search/%s.data.json" .Language.Lang -}} {{- $searchData := resources.Get "search/data.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify -}} { "dataFile": {{ $searchData.RelPermalink | jsonify }}, "indexConfig": {{ .Site.Params.geekdocSearchConfig | jsonify }}, "showParent": {{ if .Site.Params.geekdocSearchShowParent }}true{{ else }}false{{ end }}, "showDescription": {{ if .Site.Params.geekdocSearchShowDescription }}true{{ else }}false{{ end }} } ================================================ FILE: assets/search/data.json ================================================ [ {{ range $index, $page := (where .Site.Pages "Params.geekdocProtected" "ne" true) }} {{ if ne $index 0 }},{{ end }} { "id": {{ $index }}, "href": "{{ $page.RelPermalink }}", "title": {{ (partial "utils/title" $page) | jsonify }}, "parent": {{ with $page.Parent }}{{ (partial "utils/title" .) | jsonify }}{{ else }}""{{ end }}, "content": {{ $page.Plain | jsonify }}, "description": {{ $page.Summary | plainify | jsonify }} } {{ end }} ] ================================================ FILE: eslint.config.js ================================================ import eslint from "@eslint/js" import globals from "globals" import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended" export default [ eslint.configs.recommended, { languageOptions: { globals: { ...globals.browser }, ecmaVersion: "latest", sourceType: "module" }, rules: { "no-var": "error", "prefer-const": "error", "prefer-arrow-callback": "error", "prefer-template": "error", "object-shorthand": "error", "no-loop-func": "error", "no-new-object": "error", "no-array-constructor": "error", "no-prototype-builtins": "error", "prefer-spread": "error", "prefer-rest-params": "error", "default-param-last": "error", "no-useless-constructor": "error", "no-duplicate-imports": "error", "prefer-destructuring": ["error", { "VariableDeclarator": { "array": true, "object": true }, "AssignmentExpression": { "array": false, "object": false } }] } }, eslintPluginPrettierRecommended ] ================================================ FILE: exampleSite/config/_default/hugo.yaml ================================================ --- baseURL: https://geekdocs.de/ title: Geekdocs theme: hugo-geekdoc pygmentsUseClasses: true pygmentsCodeFences: true timeout: "180000s" pluralizeListTitles: false defaultContentLanguage: en disablePathToLower: true enableGitInfo: true enableRobotsTXT: true markup: goldmark: renderer: unsafe: true tableOfContents: startLevel: 1 endLevel: 9 taxonomies: tag: tags outputs: home: - HTML page: - HTML section: - HTML taxonomy: - HTML term: - HTML security: exec: allow: - "^git$" - "^asciidoctor$" ================================================ FILE: exampleSite/config/_default/languages.yaml ================================================ --- en: languageName: "English" contentDir: "content/en" weight: 10 ================================================ FILE: exampleSite/config/_default/params.yaml ================================================ --- # cspell:ignore socialmedia2 description: > Geekdoc is a simple Hugo theme for documentations. It is intentionally designed as a fast and lean theme and may not fit the requirements of complex projects. If a more feature-complete theme is required there are a lot of good alternatives out there. images: - "socialmedia2.png" geekdocToC: 3 geekdocTagsToMenu: true geekdocRepo: https://github.com/thegeeklab/hugo-geekdoc geekdocEditPath: edit/main/exampleSite geekdocPageLastmod: false geekdocSearch: true geekdocSearchShowParent: true geekdocSearchShowDescription: true geekdocLegalNotice: https://thegeeklab.de/legal-notice/#contact-information geekdocPrivacyPolicy: https://thegeeklab.de/legal-notice/#privacy-policy geekdocImageLazyLoading: true geekdocDarkModeDim: true ================================================ FILE: exampleSite/content/en/_includes/_index.md ================================================ --- geekdocHidden: true --- ================================================ FILE: exampleSite/content/en/_includes/include-page.md ================================================ _**Example page include**_ {{< hint type=note >}} **Example Shortcode**\ Shortcode used in an include page. {{< /hint >}} | Head 1 | Head 2 | Head 3 | | ------ | ------ | ------ | | 1 | 2 | 3 | ================================================ FILE: exampleSite/content/en/_index.md ================================================ --- title: Welcome to the documentation geekdocNav: false geekdocAlign: center geekdocAnchor: false --- [![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/hugo-geekdoc/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/hugo-geekdoc) [![Hugo Version](https://img.shields.io/badge/hugo-0.156-blue.svg)](https://gohugo.io) [![GitHub release](https://img.shields.io/github/v/release/thegeeklab/hugo-geekdoc)](https://github.com/thegeeklab/hugo-geekdoc/releases/latest) [![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/hugo-geekdoc)](https://github.com/thegeeklab/hugo-geekdoc/graphs/contributors) [![License: MIT](https://img.shields.io/github/license/thegeeklab/hugo-geekdoc)](https://github.com/thegeeklab/hugo-geekdoc/blob/main/LICENSE) Geekdoc is a simple Hugo theme for documentations. It is intentionally designed as a fast and lean theme and may not fit the requirements of complex projects. If a more feature-complete theme is required there are a lot of great alternatives out there. {{< button size="large" relref="usage/getting-started/" >}}Getting Started{{< /button >}} ## Feature overview {{< columns >}} ### Clean and simple design Stay focused on exploring the content and don't get overwhelmed by a complex design. <---> ### Light and mobile-friendly The theme is powered by less than 1 MB and looks impressive on mobile devices as well as on a regular Desktop. <---> ### Easy customization The look and feel can be easily customized by CSS custom properties (variables), features can be adjusted by Hugo parameters. {{< /columns >}} {{< columns >}} ### Zero initial configuration Getting started in minutes. The theme is shipped with a default configuration and works out of the box. <---> ### Handy shortcodes We included some (hopefully) useful custom shortcodes so you don't have to and can focus on writing amazing docs. <---> ### Dark mode Powerful dark mode that detects your system preferences or can be controlled by a toggle switch. {{< /columns >}} ================================================ FILE: exampleSite/content/en/asciidoc/admonition-icons.adoc ================================================ +++ title = "Admonition Icons" +++ :icons: font By default, the admonition is rendered with a plain text label. To enable font icons the document attribute `:icons: font` need to be set. == Example [NOTE] Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. [TIP] Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. [IMPORTANT] Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. [CAUTION] Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. [WARNING] Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. ================================================ FILE: exampleSite/content/en/asciidoc/admonitions.adoc ================================================ +++ title = "Admonitions" +++ // cspell:ignore toclevels :toc: :toclevels: 2 {{< toc >}} == Admonition types There are certain statements you may want to draw attention to by taking them out of the content's flow and labeling them with a priority. These are called admonitions. ```tpl [NOTE|TIP|IMPORTANT|CAUTION|WARNING] Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. ``` === Example [NOTE] Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. [TIP] Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. [IMPORTANT] Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. [CAUTION] Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. [WARNING] ==== Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Romanesque acclimates investiture. ==== == Admonition icons Icons can be added by setting a unicode glyph or a character reference to the `tip-caption` attribute: ```text :tip-caption: 💡 [TIP] It's possible to use Unicode glyphs as admonition icons. ``` ```text :tip-caption: pass:[🔥] [TIP] It's possible to use Unicode glyphs as admonition icons. ``` === Example :tip-caption: 💡 [TIP] It's possible to use Unicode glyphs as admonition icons. :tip-caption: pass:[🔥] [TIP] It's possible to use Unicode glyphs as admonition icons. ================================================ FILE: exampleSite/content/en/collapse/_index.md ================================================ --- title: Collapse geekdocCollapseSection: true --- Demo collapsible menu entries. ================================================ FILE: exampleSite/content/en/collapse/level-1/_index.md ================================================ Level 1 {{< toc-tree >}} ================================================ FILE: exampleSite/content/en/collapse/level-1/level-1-1.md ================================================ --- title: Level 1.1 --- Level 1.1 ================================================ FILE: exampleSite/content/en/collapse/level-1/level-1-2.md ================================================ --- title: Level 1.2 --- Level 1.2 ================================================ FILE: exampleSite/content/en/collapse/level-2/_index.md ================================================ --- geekdocCollapseSection: true --- Level-2 ================================================ FILE: exampleSite/content/en/collapse/level-2/level-2-1.md ================================================ --- title: Level 2.1 --- Level 2.1 ================================================ FILE: exampleSite/content/en/collapse/level-2/level-2-2.md ================================================ --- title: Level 2.2 --- Level 2.2 ================================================ FILE: exampleSite/content/en/features/_index.md ================================================ --- title: Features weight: -15 --- ================================================ FILE: exampleSite/content/en/features/code-blocks.md ================================================ --- title: Code Blocks --- There are several ways to add code blocks. Most of them work out of the box, only the Hugo shortcode `` needs to be configured to work properly. The theme also provides some additional features like a copy button and an option to set the maximum length of code blocks. Both of these functions and the dependent formatting rely on the `.highlight` CSS class. You must ensure that you always assign a language to your code blocks if you want to use these functions. If you do not want to apply syntax highlighting, you can also specify `plain` or `text` as the language. {{< toc >}} ## Inline code To display an inline shortcode use single quotes: ```plain `some code` ``` **Example:** `some code` with a [`link`](#) ## Code blocks Code blocks can be uses without language specification: ````markdown ```plain some code ``` ```` **Example:** ```plain some code ``` ... or if you need language specific syntax highlighting: ````markdown ```shell # some code echo "Hello world" ``` ```` **Example:** ```shell # some code echo "Hello World" ``` ## Highlight shortcode Hugo has a build-in shortcode for syntax highlighting. To work properly with this theme, you have to set following options in your site configuration: {{< tabs "uniqueid" >}} {{< tab "TOML" >}} ```toml pygmentsUseClasses=true pygmentsCodeFences=true ``` {{< /tab >}} {{< tab "YAML" >}} ```yaml pygmentsUseClasses: true pygmentsCodeFences: true ``` {{< /tab >}} {{< /tabs >}} You can use it like every other shortcode: ```markdown {{}} # some code echo "Hello World" {{}} ``` **Example:** {{< highlight Shell "linenos=table" >}} # some code echo "Hello World" {{< /highlight >}} ## Gist Shortcode The Gist shortcode is a built-in Hugo shortcode to load GitHub gists. For details usage information please check the Hugo [documentation](https://gohugo.io/content-management/shortcodes/#gist). ```markdown {{}} ``` **Example:** {{< gist spf13 7896402 >}} ================================================ FILE: exampleSite/content/en/features/dark-mode/_index.md ================================================ --- title: Dark Mode --- Say hello to the dark mode of the Geekdoc theme! [![Geekdoc in dark mode](images/geekdoc-dark.png)](images/geekdoc-dark.png) The dark mode can be used in two different ways. If you have JavaScript disabled in your browser, the dark mode automatically detects the preferred system settings via the `prefers-color-scheme` parameter. Depending on the value, the theme will automatically switch between dark and light mode if this feature is supported by your operating system and browser. The second mode requires JavaScript and is controlled by a dark mode switch in the upper right corner. You can switch between three modes: Auto, Dark and Light. Auto mode works the same as the first method mentioned above and automatically detects the system setting. Dark and Light modes allow you to force one of them for your Geekdoc page only, regardless of the system setting. This works even if your browser or operating system does not support the system setting. The current selection is stored locally via the Web Storage API. To avoid very bright spots often caused by images while using the dark mode we have added an optional auto-dim feature that can be enabled with the site parameter `geekdocDarkModeDim` (see [Configuration](/usage/configuration/)). As this may have an impact on the quality of the images it is disabled by default. ================================================ FILE: exampleSite/content/en/features/icon-sets.md ================================================ --- title: Icon Sets # cSpell:ignore svgsprit.es --- {{< toc >}} ## Custom icon sets The only supported source for custom icons are SVG sprites. Some icon frameworks provides ready to use sprites e.g. FontAwesome. If the framework don't provide sprites, you can create your own from raw SVG icons. There are a lot of tools available to create sprites, please choose one that fits your need. One solution could be [svgsprit.es](https://svgsprit.es/). Regardless of which tool (or existing sprite) you choose, there are a few requirements that must be met: 1. The sprite must be a valid **SVG** file. 2. You have to ensure to **hide the sprite**. Apply the predefined class `svg-sprite` or `hidden` to the root element of your sprite or add a small piece of inline CSS e.g. `style="display: none;"`. 3. Save the sprite to the folder `assets/sprites` right beside your `content` folder. The result of a valid minimal SVG sprite file could look like this: ```xml ``` **Example:** FontAwesome provides three pre-build sprites included in the regular Web download pack, `sprites/brands.svg`, `sprites/regular.svg` and `sprites/solid.svg`. Choose your sprite to use and copy it to your project's root directory into `assets/sprites`, right beside your `content` folder: ```bash my_project/ ├── assets │   └── sprites │   └── regular.svg ├── hugo.toml ├── content │   ├── _index.md │   ├── ... ``` That's it! The theme will auto-load all available SVG sprites provided in the assets folder. To use the icons e.g. in the [bundle menu](/usage/menus/#bundle-menu), you need to lookup the id of the icon. An example would be `thumbs-up` {{< icon "thumbs-up" >}}. There is also a [shortcode](/shortcodes/icons/) available. ## Build-in icons The theme bundles just a small set of hand crafted icons. {{< sprites >}} ================================================ FILE: exampleSite/content/en/features/multilingual/_index.md ================================================ --- title: Multilingual # cSpell:ignore Veröffentlichung --- {{< toc >}} Hugo supports the creation of websites with multiple languages. In this post we will explain how to get configure Multilingual Mode with this theme. ## Configuration ### Languages You need to set a default language and configure at least two different languages used by your site to your configuration file at `hugo.toml`: ```toml defaultContentLanguage = "en" [languages.en] languageName = "English" contentDir = "content/en" weight = 10 [languages.de] languageName = "German" contentDir = "content/de" weight = 20 ``` ### Translation Strings To customize translation strings used by the theme you can create a file `i18n/.toml` for every language you want to use e.g. `i18n/en.toml`. You can lookup all used strings in the [default](https://github.com/thegeeklab/hugo-geekdoc/blob/main/i18n/en.yaml) translation file. ### Menus For the [Bundle Menu](/usage/menus/#bundle-menu) as well as for the [Extra Header Menu](/usage/menus/#extra-header-menu) you can translate the name within the data file of the menu: ```yaml --- more: # If `name` is a text, this text will be used as name for each language. - name: News ref: "/#" icon: "gdoc_notification" # To translate the name you can add a sub-item per language. Important: If you miss a language key # that is configured in the languages list of your `hugo.toml` the name will be empty for this language! - name: en: Releases de: Veröffentlichung ref: "https://github.com/thegeeklab/hugo-geekdoc/releases" external: true icon: "gdoc_download" ``` ## Add Content To translate your content you need to create a directory `content//` for each language you want to use e.g. `content/en/`. This language directories will hold the translated pages for the particular language. ## Switch Content If you have configured at least two different languages, the language switcher will be enabled in the UI automatically. The switcher is as part of the header menu and displayed on all pages. {{< columns >}} [![Beach Color Palette](images/translation-available.png)](images/translation-available.png) On pages for which a translation is available it will be displayed in the selection list and links to the translated page. <---> [![Beach Color Palette](images/translation-not-available.png)](images/translation-not-available.png) Pages without a translation will be displayed in the selection list as well but are marked with an asterisk and link to the start page of the respective language. {{< /columns >}} ================================================ FILE: exampleSite/content/en/features/theming/_index.md ================================================ --- title: Theming # cspell:ignore msapplication --- {{< toc >}} ## Color Scheme If you want to customize the theme's color scheme to give it your individual touch, you are only a few lines of CSS away. Generally, you need to override the default settings. The easiest way to do this is to create a file named `static/custom.css` right at the root of your site. All the necessary CSS customization properties are listed below. If you want to customize elements that don't use these properties, you can always look up the class name and override it directly. For inspiration, you can also take a look at [https://www.color-hex.com](https://www.color-hex.com/color-palettes/). In this simple example, we'll use the [_Beach_](https://www.color-hex.com/color-palette/895) color palette. [![Beach Color Palette](images/theme-example.png)](images/theme-example.png) **Custom CSS:** {{< include file="/static/custom.css.example" language="CSS" options="linenos=table" >}} ## Favicons The Theme is shipped with a set of default Favicons in various formats generated by the [Favicon Generator](https://realfavicongenerator.net/). All files can be found in the `static/favicon` folder of the release tarball. To make the replacement of the default Favicons as simple as possible, the theme loads only a very small subset of the Favicon formats. ```tpl ``` ### Simple replacement The minimal steps to load a custom Favicon is to overwrite the three default Favicon files. Therefore place these files into your projects root folder: - `static/favicon/favicon.svg` - `static/favicon/favicon-32x32.png` - `static/favicon/favicon-16x16.png` ### Full replacement If you want to add more Favicon formats you have to [overwrite](https://gohugo.io/templates/lookup-order/) the default partial that is used to load the files. In the next step you have to place the required files in the `static` folder of your project as well. **Example:** ```tpl ``` ## Fonts To use a custom font, it needs to be specified first. While there are many ways to do this, we recommend to use `@font-face` as it supports local as well as remote fonts. If you want to serve the fonts from your own server, you have to place them in the `static/fonts` folder of your project. The font registration is done in the `custom.css` file. There are also a few custom CSS properties available to simplify the usage of custom fonts. **Example:** ```css @font-face { font-family: "DancingScript"; src: url("fonts/DancingScript.woff2") format("woff2"), url("fonts/DancingScript.woff") format("woff"); font-weight: normal; font-style: normal; font-display: swap; } :root { --code-max-height: 60rem; --header-font-family: "DancingScript"; --body-font-family: "DancingScript"; --code-font-family: "DancingScript"; } ``` Happy customizing! ================================================ FILE: exampleSite/content/en/posts/_index.md ================================================ --- title: News type: posts weight: 10 geekdocHidden: true --- ================================================ FILE: exampleSite/content/en/posts/hello_geekdoc.md ================================================ --- title: Hello Geekdoc type: posts date: 2020-01-06 tags: - Documentation - Updates --- This is the first release of the Geekdoc theme. Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. Amalia id per in minimum facility, quid facet modifier ea ma. Ill um select ma ad, en ferric patine sentient vim. Per expendable foreordained interpretations cu, maxim sole pertinacity in ram. Que no rota alters, ad sea sues exercise main rum, cu diam mas facility sea. ================================================ FILE: exampleSite/content/en/posts/initial-release.md ================================================ --- title: Initial release type: posts date: 2020-01-08 --- This is the first release of the Geekdoc theme. Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. ================================================ FILE: exampleSite/content/en/shortcodes/_index.md ================================================ --- title: Shortcodes weight: -10 --- ================================================ FILE: exampleSite/content/en/shortcodes/audio/_index.md ================================================ --- title: Audio resources: - name: diamonds-trap src: "diamonds-trap.mp3" title: Diamonds Trap params: credits: "[Jakob Eglmeier on openmusic.academy CC0-1.0](https://openmusic.academy/media-library/b9do2E2ZwVCfppyBf2yuej)" # cspell:ignore Jakob Eglmeier openmusic --- The audio shortcode allows you to embed audio files. ## Usage Define your resources in the page front matter, custom parameter `params.credits` is optional. ```md --- resources: - name: diamonds-trap src: "diamonds-trap.mp3" title: Diamonds Trap params: credits: "[Jakob Eglmeier on openmusic.academy CC0-1.0](https://openmusic.academy/media-library/b9do2E2ZwVCfppyBf2yuej)" --- {{}} ``` ### Attributes {{< propertylist name=shortcode-audio sort=name order=asc >}} ## Example {{< audio name="diamonds-trap" >}} ================================================ FILE: exampleSite/content/en/shortcodes/avatar/_index.md ================================================ --- title: Avatar resources: - name: avatar src: "avatar.jpg" title: "Avatar" --- The avatar shortcode is another custom image shortcode. ## Usage Define a resource in the page front matter. ```md --- resources: - name: avatar src: "images/avatar.jpg" title: "Avatar" --- {{}} ``` ## Attributes {{< propertylist name=shortcode-avatar sort=name order=asc >}} ## Example {{< avatar name=avatar size="small" >}} ================================================ FILE: exampleSite/content/en/shortcodes/buttons.md ================================================ --- title: Buttons --- Buttons are styled links that can lead to local page or external link. ## Usage ```tpl {{}}Get Home{{}} {{}}Contribute{{}} ``` ### Attributes {{< propertylist name=shortcode-buttons sort=name order=asc >}} ## Example {{< button relref="/" >}}Get Home{{< /button >}} {{< button href="https://github.com/thegeeklab/hugo-geekdoc" >}}Contribute{{< /button >}} ================================================ FILE: exampleSite/content/en/shortcodes/columns.md ================================================ --- title: Columns --- The Columns shortcode can be used to organize content side-by-side (horizontally) for better readability. ## Usage ```html {{}} ## Left Content Dolor sit, sumo unique argument um no ... <---> ## Mid Content Dolor sit, sumo unique argument um no ... <---> ## Right Content Dolor sit, sumo unique argument um no ... {{}} ``` ### Attributes {{< propertylist name=shortcode-columns sort=name order=asc >}} ## Example {{< columns >}} ### Left Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. <---> ### Mid Content Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. <---> ### Right Content Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. {{< /columns >}} ================================================ FILE: exampleSite/content/en/shortcodes/expand.md ================================================ --- title: Expand --- Expand shortcode can help to decrease clutter on screen by hiding part of text. Expand content by clicking on it. ## Usage ```tpl {{}} ### Markdown content Dolor sit, sumo unique ... {{}} ``` It is also possible to use a custom label and symbol. ```tpl {{}} ### More markdown Dolor sit, sumo unique ... {{}} ``` ## Example {{< expand >}} ### Markdown content Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. {{< /expand >}} {{< expand "Custom Label" "..." >}} ### More markdown Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. {{< /expand >}} ================================================ FILE: exampleSite/content/en/shortcodes/hints.md ================================================ --- title: Hints --- Hint shortcode can be used as hint/alerts/notification block. ## Usage ```tpl {{}} **Markdown content**\ Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. {{}} ``` ### Attributes {{< propertylist name=shortcode-hints sort=name order=asc >}} ## Example {{< hint type=note >}} **Markdown content**\ Dolor sit, sumo unique `argument um no`. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. {{< /hint >}} {{< hint type=tip >}} **Markdown content**\ Dolor sit, sumo unique `argument um no`. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. {{< /hint >}} {{< hint type=important >}} **Markdown content**\ Dolor sit, sumo unique `argument um no`. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. {{< /hint >}} {{< hint type=caution >}} **Markdown content**\ Dolor sit, sumo unique `argument um no`. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. {{< /hint >}} {{< hint type=warning >}} **Markdown content**\ Dolor sit, sumo unique `argument um no`. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Romanesque acclimates investiture. {{< /hint >}} Example with a custom icon and title: {{< hint type=note icon=gdoc_github title=GitHub >}} **Markdown content**\ Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. {{< /hint >}} ================================================ FILE: exampleSite/content/en/shortcodes/icons.md ================================================ --- title: Icons --- Simple shortcode to include icons from SVG sprites outside of menus. ## Usage ```tpl {{}} ``` ## Example | Output | Code | | -------------------------- | -------------------------------- | | {{< icon "thumbs-up" >}} | `{{}}` | | {{< icon "thumbs-down" >}} | `{{}}` | | {{< icon "laugh" >}} | `{{}}` | | {{< icon "lemon" >}} | `{{}}` | | {{< icon "moon" >}} | `{{}}` | ================================================ FILE: exampleSite/content/en/shortcodes/images/_index.md ================================================ --- title: Images resources: - name: forest-1 src: "forest-1.jpg" title: Forest (1) params: credits: "[Jay Mantri](https://unsplash.com/@jaymantri) on [Unsplash](https://unsplash.com/s/photos/forest)" - name: forest-2 src: "forest-2.jpg" title: Forest (2) params: credits: "[Jay Mantri](https://unsplash.com/@jaymantri) on [Unsplash](https://unsplash.com/s/photos/forest)" - name: forest-3 src: "forest-3.jpg" title: Forest (3) params: credits: "[Jay Mantri](https://unsplash.com/@jaymantri) on [Unsplash](https://unsplash.com/s/photos/forest)" - name: forest-4 src: "forest-4.jpg" title: Forest (4) params: credits: "[Jay Mantri](https://unsplash.com/@jaymantri) on [Unsplash](https://unsplash.com/s/photos/forest)" - name: forest-5 src: "forest-5.jpg" title: Forest (5) params: credits: "[Jay Mantri](https://unsplash.com/@jaymantri) on [Unsplash](https://unsplash.com/s/photos/forest)" - name: forest-6 src: "forest-6.jpg" title: Forest (6) params: credits: "[Asher Ward](https://unsplash.com/@the_asher_ward) on [Unsplash](https://unsplash.com/s/photos/forest)" - name: forest-7 src: "forest-7.jpg" title: Forest (7) params: credits: "[Asher Ward](https://unsplash.com/@the_asher_ward) on [Unsplash](https://unsplash.com/s/photos/forest)" - name: forest-8 src: "forest-8.svg" title: Forest (8) params: credits: "SVG Repo" # cspell:ignore Mantri --- If you need more flexibility for your embedded images, you could use the `img` shortcode. It is using Hugo's [page resources](https://gohugo.io/content-management/page-resources/) and supports lazy loading of your images. ## Usage Define your resources in the page front matter, custom parameter `params.credits` is optional. ```md --- resources: - name: forest-1 src: "forest-1.jpg" title: Forest (1) params: credits: "[Jay Mantri](https://unsplash.com/@jaymantri) on [Unsplash](https://unsplash.com/s/photos/forest)" --- {{}} ``` ### Attributes {{< propertylist name=shortcode-images sort=name order=asc >}} ## Example {{< img name="forest-1" lazy=false >}} Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. {{< img name="forest-2" lazy=true >}} Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. {{< img name="forest-3" lazy=true >}} Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. {{< img name="forest-4" lazy=true >}} Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. {{< img name="forest-5" lazy=true >}} Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. {{< img name="forest-6" lazy=true >}} Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. {{< img name="forest-7" lazy=true >}} Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. {{< img name="forest-8" size=small lazy=true >}} ================================================ FILE: exampleSite/content/en/shortcodes/includes.md ================================================ --- title: Includes --- Include shortcode can include files of different types. By specifying a language, the included file will have syntax highlighting. ## Usage ```tpl {{}} ``` ### Attributes {{< propertylist name=shortcode-includes sort=name order=asc >}} ## Example ### Example 1: Markdown file (default) If no other options are specified, files will be rendered as Markdown using the `RenderString` [function](https://gohugo.io/functions/renderstring/). {{< hint type=important >}} **Location of markdown files**\ If you include markdown files that should not get a menu entry, place them outside the content folder or exclude them otherwise. {{< /hint >}} ```tpl {{}} ``` {{< include file="/static/_includes/example.md.part" >}} ### Example 2: Language files This method can be used to include source code files and keep them automatically up to date. ```tpl {{}} ``` Result: {{< include file="config/_default/hugo.yaml" language="yaml" options="linenos=table,hl_lines=5-6,linenostart=100" >}} ### Example 3: HTML HTML content will be filtered by the `safeHTML` filter and added to the rendered page output. ```tpl {{}} ``` {{< include file="/static/_includes/example.html.part" type="html" >}} ### Example 4: Hugo Pages In some situations, it can be helpful to include Markdown files that also contain shortcodes. While the [default method](#example-1-markdown-file-default) works fine to render plain Markdown, shortcodes are not parsed. The only way to get this to work is to use Hugo pages. There are several ways to structure these include pages, so whatever you do, keep in mind that Hugo needs to be able to render and serve these files as regular pages! How it works: 1. First you need to create a directory **within** your content directory. For this example site `_includes` is used. 2. To prevent the theme from embedding the page in the navigation, create a file `_includes/_index.md` and add `geekdocHidden: true` to the front matter. 3. Place your Markdown files within the `_includes` folder e.g. `/_includes/include-page.md`. Make sure to name it `*.md`. 4. Include the page using `{{}}`. Resulting structure should look like this: ```shell _includes/ ├── include-page.md └── _index.md ``` {{< include file="/_includes/include-page.md" type="page" >}} ================================================ FILE: exampleSite/content/en/shortcodes/katex.md ================================================ --- title: KaTeX # cspell:ignore infty --- [KaTeX](https://katex.org/) shortcode let you render math typesetting in markdown document. ## Usage ```latex {{}} f(x) = \int_{-\infty}^\infty\hat f(\xi)\,e^{2 \pi i \xi x}\,d\xi {{}} ``` ### Attributes {{< propertylist name=shortcode-katex sort=name order=asc >}} ## Example {{< katex display >}} f(x) = \int_{-\infty}^\infty\hat f(\xi)\,e^{2 \pi i \xi x}\,d\xi {{< /katex >}} KaTeX can be used inline, for example {{< katex >}}\pi(x){{< /katex >}} or used with the `display` parameter as above. ================================================ FILE: exampleSite/content/en/shortcodes/mermaid.md ================================================ --- title: Mermaid --- [Mermaid](https://mermaidjs.github.io/) is library for generating SVG charts and diagrams from text. ## Usage ```tpl {{}} sequenceDiagram Alice->>Bob: Hello Bob, how are you? alt is sick Bob->>Alice: Not so good :( else is well Bob->>Alice: Feeling fresh like a daisy end opt Extra response Bob->>Alice: Thanks for asking end {{}} ``` ### Attributes {{< propertylist name=shortcode-mermaid sort=name order=asc >}} ## Example {{< mermaid class="text-center" >}} sequenceDiagram Alice->>Bob: Hello Bob, how are you? alt is sick Bob->>Alice: Not so good :( else is well Bob->>Alice: Feeling fresh like a daisy end opt Extra response Bob->>Alice: Thanks for asking end {{< /mermaid >}} As an alternative to shortcodes, code blocks can be used for markdown as well. {{< columns >}} ````tpl ```mermaid flowchart LR A[Hard] -->|Text| B(Round) B --> C{Decision} C -->|One| D[Result 1] C -->|Two| E[Result 2] ``` ```` <---> ```mermaid flowchart LR A[Hard] -->|Text| B(Round) B --> C{Decision} C -->|One| D[Result 1] C -->|Two| E[Result 2] ``` {{< /columns >}} ================================================ FILE: exampleSite/content/en/shortcodes/progress.md ================================================ --- title: Progress --- A progress bar shows how far a process has progressed. ## Usage ```tpl {{}} ``` ### Attributes {{< propertylist name=shortcode-progress sort=name order=asc >}} ## Example {{< progress title=Eating value=65 icon=gdoc_heart >}} {{< progress title="Type: note" value=10 icon=gdoc_heart type=note >}} {{< progress title="Type: tip" value=70 icon=gdoc_heart type=tip >}} {{< progress title="Type: important" value=30 icon=gdoc_heart type=important >}} {{< progress title="Type: caution" value=90 icon=gdoc_heart type=caution >}} {{< progress title="Type: warning" value=80 icon=gdoc_heart type=warning >}} ================================================ FILE: exampleSite/content/en/shortcodes/propertylist.md ================================================ --- title: Properties --- The property list shortcode creates a custom HTML description list that can be used to display properties or variables and general dependent information. The shortcode requires a data file in `data/properties/`, e.g. `data/properties/demo.yaml`. ## Usage ```tpl {{}} ``` The supported attributes can be taken from the following example: {{< include file="/data/properties/demo.yaml" language="Yaml" options="linenos=table" >}} ### Attributes {{< propertylist name=shortcode-buttons sort=name order=asc >}} ## Example {{< propertylist name=demo sort=name order=asc >}} ================================================ FILE: exampleSite/content/en/shortcodes/tabs.md ================================================ --- title: Tabs --- Tabs let you organize content by context, for example installation instructions for each supported platform. ## Usage ```tpl {{}} {{}} # macOS Content {{}} {{}} # Linux Content {{}} {{}} # Windows Content {{}} {{}} ``` ## Example {{< tabs "uniqueid" >}} {{< tab "macOS" >}} ## macOS This is tab **macOS** content. Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. {{< /tab >}} {{< tab "Linux" >}} ## Linux This is tab **Linux** content. Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. {{< /tab >}} {{< tab "Windows" >}} ## Windows This is tab **Windows** content. Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent. {{< /tab >}} {{< /tabs >}} ================================================ FILE: exampleSite/content/en/shortcodes/toc-tree.md ================================================ --- title: ToC-Tree --- The `toc-tree` shortcode will generate a Table of Content from a section file tree of your content directory. The root of the resulting ToC will be the page on which you define the shortcode. ## Usage ```tpl {{}} ``` ### Attributes {{< propertylist name=shortcode-toc-tree sort=name order=asc >}} ## Example As said, the root will be the site on which the shortcode was used, you can see a demo including nesting in the [ToC Tree](/toc-tree/) section. ================================================ FILE: exampleSite/content/en/shortcodes/toc.md ================================================ --- title: ToC --- Simple wrapper to generate a page Table of Content from a shortcode. ## Usage ```tpl {{}} ``` ### Attributes {{< propertylist name=shortcode-toc sort=name order=asc >}} ## Example {{< toc >}} ## Level 1 Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. ## Level 2 Amalia id per in minimum facility, quid facet modifier ea ma. Ill um select ma ad, en ferric patine sentient vim. Per expendable foreordained interpretations cu, maxim sole pertinacity in ram. ### Level 2.1 Amalia id per in minimum facility, quid facet modifier ea ma. Ill um select ma ad, en ferric patine sentient vim. Per expendable foreordained interpretations cu, maxim sole pertinacity in ram. #### Level 2.1.1 Amalia id per in minimum facility, quid facet modifier ea ma. Ill um select ma ad, en ferric patine sentient vim. ##### Level 2.1.1.1 In pro quints consequent, denim fastidious copious quo ad. ###### Level 2.1.1.1.1 In pro quints consequent, denim fastidious copious quo ad. ### Level 2.2 Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. Amalia id per in minimum facility, quid facet modifier ea ma. Ill um select ma ad, en ferric patine sentient vim. Per expendable foreordained interpretations cu, maxim sole pertinacity in ram. ================================================ FILE: exampleSite/content/en/toc-tree/_index.md ================================================ --- title: ToC-Tree geekdocFlatSection: true --- This is just a demo section for the [toc-tree](/shortcodes/toc-tree/) shortcode. {{< toc-tree >}} ================================================ FILE: exampleSite/content/en/toc-tree/level-1/_index.md ================================================ --- geekdocCollapseSection: true --- Level 1 {{< toc-tree >}} ================================================ FILE: exampleSite/content/en/toc-tree/level-1/level-1-1.md ================================================ --- title: Level 1.1 --- Level 1.1 ================================================ FILE: exampleSite/content/en/toc-tree/level-1/level-1-2.md ================================================ --- title: Level 1.2 --- Level 1.2 ================================================ FILE: exampleSite/content/en/toc-tree/level-1/level-1-3/_index.md ================================================ --- title: Level 1.3 --- Level 1.3 {{< toc-tree >}} ================================================ FILE: exampleSite/content/en/toc-tree/level-1/level-1-3/level-1-3-1.md ================================================ --- title: Level 1.3.1 --- Level 1.3.1 ================================================ FILE: exampleSite/content/en/toc-tree/level-2/_index.md ================================================ Level-2 ================================================ FILE: exampleSite/content/en/toc-tree/level-2/level-2-1.md ================================================ --- title: Level 2.1 --- Level 2.1 ================================================ FILE: exampleSite/content/en/toc-tree/level-2/level-2-2.md ================================================ --- title: Level 2.2 --- Level 2.2 ================================================ FILE: exampleSite/content/en/usage/_index.md ================================================ --- title: Usage weight: -20 --- ================================================ FILE: exampleSite/content/en/usage/configuration.md ================================================ --- title: Configuration weight: -10 # cspell:ignore expirydate linktitle publishdate --- {{< toc >}} ## Site configuration {{< tabs "site-config" >}} {{< tab "TOML" >}} ```toml baseURL = "http://localhost" title = "Geekdocs" theme = "hugo-geekdoc" # Required to get well formatted code blocks pygmentsUseClasses = true pygmentsCodeFences = true disablePathToLower = true enableGitInfo = true # Required if you want to render robots.txt template enableRobotsTXT = true [markup] [markup.goldmark.renderer] # Needed for mermaid shortcode or when nesting shortcodes (e.g. img within # columns or tabs) unsafe = true [markup.tableOfContents] startLevel = 1 endLevel = 9 [taxonomies] tag = "tags" [params] # (Optional, default none) Set a subtitle used in the page header. geekdocSubtitle = "A Hugo theme for documentation" # (Optional, default 6) Set how many table of contents levels to be showed on page. # Use false to hide ToC, note that 0 will default to 6 (https://gohugo.io/functions/default/) # You can also specify this parameter per page in front matter. geekdocToC = 3 # (Optional, default static/brand.svg) Set the path to a logo for the Geekdoc # relative to your 'static/' folder. geekdocLogo = "logo.png" # (Optional, default false) Render menu from data file in 'data/menu/main.yaml'. # See also https://geekdocs.de/usage/menus/#bundle-menu. geekdocMenuBundle = true # (Optional, default false) Collapse all menu entries, cannot be overwritten # per page if enabled. Can be enabled per page via 'geekdocCollapseSection'. geekdocCollapseAllSections = true # (Optional, default true) Show page navigation links at the bottom of each docs page. geekdocNextPrev = false # (Optional, default true) Show a breadcrumb navigation bar at the top of each docs page. # You can also specify this parameter per page in front matter. geekdocBreadcrumb = false # (Optional, default none) Set source repository location. Used for 'Edit page' links. # You can also specify this parameter per page in front matter. geekdocRepo = "https://github.com/thegeeklab/hugo" # (Optional, default none) Enable 'Edit page' links. Requires 'geekdocRepo' param # and the path must point to the parent directory of the 'content' folder. # You can also specify this parameter per page in front matter. geekdocEditPath = "edit/main/exampleSite" # (Optional, default false) Show last modification date of the page in the header. # Keep in mind that last modification date works best if `enableGitInfo` is set to true. geekdocPageLastmod = true # (Optional, default true) Enables search function with flexsearch. # Index is built on the fly and might slow down your website. geekdocSearch = false # (Optional, default false) Display search results with the parent folder as prefix. This # option allows you to distinguish between files with the same name in different folders. # NOTE: This parameter only applies when 'geekdocSearch = true'. geekdocSearchShowParent = true # (Optional, default none) Add a link to your Legal Notice page to the site footer. # It can be either a remote url or a local file path relative to your content directory. geekdocLegalNotice = "https://blog.example.com/legal" # (Optional, default none) Add a link to your Privacy Policy page to the site footer. # It can be either a remote url or a local file path relative to your content directory. geekdocPrivacyPolicy = "/privacy" # (Optional, default true) Add an anchor link to headlines. geekdocAnchor = true # (Optional, default true) Copy anchor url to clipboard on click. geekdocAnchorCopy = true # (Optional, default true) Enable or disable image lazy loading for images rendered # by the 'img' shortcode. geekdocImageLazyLoading = true # (Optional, default false) Set HTMl to .Site.Home.Permalink if enabled. It might be required # if a subdirectory is used within Hugo's BaseURL. # See https://developer.mozilla.org/de/docs/Web/HTML/Element/base. geekdocOverwriteHTMLBase = false # (Optional, default true) Enable or disable the JavaScript based color theme toggle switch. The CSS based # user preference mode still works. geekdocDarkModeToggle = false # (Optional, default false) Auto-decrease brightness of images and add a slightly grayscale to avoid # bright spots while using the dark mode. geekdocDarkModeDim = false # (Optional, default false) Enforce code blocks to always use the dark color theme. geekdocDarkModeCode = false # (Optional, default true) Display a "Back to top" link in the site footer. geekdocBackToTop = true # (Optional, default false) Enable or disable adding tags for post pages automatically to the navigation sidebar. geekdocTagsToMenu = true # (Optional, default 'title') Configure how to sort file-tree menu entries. Possible options are 'title', 'linktitle', # 'date', 'publishdate', 'expirydate' or 'lastmod'. Every option can be used with a reverse modifier as well # e.g. 'title_reverse'. geekdocFileTreeSortBy = "title" # (Optional, default none) Adds a "Content licensed under " line to the footer. # Could be used if you want to define a default license for your content. [params.geekdocContentLicense] name = "CC BY-SA 4.0" link = "https://creativecommons.org/licenses/by-sa/4.0/" ``` {{< /tab >}} {{< tab "YAML" >}} ```yaml --- baseURL: "http://localhost" title: "Geekdocs" theme: "hugo-geekdoc" # Required to get well formatted code blocks pygmentsUseClasses: true pygmentsCodeFences: true disablePathToLower: true enableGitInfo: true # Required if you want to render robots.txt template enableRobotsTXT: true markup: goldmark: # Needed for mermaid shortcode or when nesting shortcodes (e.g. img within # columns or tabs) renderer: unsafe: true tableOfContents: startLevel: 1 endLevel: 9 taxonomies: tag: tags params: # (Optional, default none) Set a subtitle used in the page header. geekdocSubtitle: "A Hugo theme for documentation" # (Optional, default 6) Set how many table of contents levels to be showed on page. # Use false to hide ToC, note that 0 will default to 6 (https://gohugo.io/functions/default/) # You can also specify this parameter per page in front matter. geekdocToC: 3 # (Optional, default static/brand.svg) Set the path to a logo for the Geekdoc # relative to your 'static/' folder. geekdocLogo: logo.png # (Optional, default false) Render menu from data file in 'data/menu/main.yaml'. # See also https://geekdocs.de/usage/menus/#bundle-menu. geekdocMenuBundle: true # (Optional, default false) Collapse all menu entries, cannot be overwritten # per page if enabled. Can be enabled per page via 'geekdocCollapseSection'. geekdocCollapseAllSections: true # (Optional, default true) Show page navigation links at the bottom of each docs page. geekdocNextPrev: false # (Optional, default true) Show a breadcrumb navigation bar at the top of each docs page. # You can also specify this parameter per page in front matter. geekdocBreadcrumb: false # (Optional, default none) Set source repository location. Used for 'Edit page' links. # You can also specify this parameter per page in front matter. geekdocRepo: "https://github.com/thegeeklab/hugo-geekdoc" # (Optional, default none) Enable 'Edit page' links. Requires 'geekdocRepo' param # and the path must point to the parent directory of the 'content' folder. # You can also specify this parameter per page in front matter. geekdocEditPath: edit/main/exampleSite # (Optional, default false) Show last modification date of the page in the header. # Keep in mind that last modification date works best if `enableGitInfo` is set to true. geekdocPageLastmod: true # (Optional, default true) Enables search function with flexsearch. # Index is built on the fly and might slow down your website. geekdocSearch: false # (Optional, default false) Display search results with the parent folder as prefix. This # option allows you to distinguish between files with the same name in different folders. # NOTE: This parameter only applies when 'geekdocSearch: true'. geekdocSearchShowParent: true # (Optional, default none) Add a link to your Legal Notice page to the site footer. # It can be either a remote url or a local file path relative to your content directory. geekdocLegalNotice: "https://blog.example.com/legal" # (Optional, default none) Add a link to your Privacy Policy page to the site footer. # It can be either a remote url or a local file path relative to your content directory. geekdocPrivacyPolicy: "/privacy" # (Optional, default true) Add an anchor link to headlines. geekdocAnchor: true # (Optional, default true) Copy anchor url to clipboard on click. geekdocAnchorCopy: true # (Optional, default true) Enable or disable image lazy loading for images rendered # by the 'img' shortcode. geekdocImageLazyLoading: true # (Optional, default false) Set HTMl to .Site.Home.Permalink if enabled. It might be required # if a subdirectory is used within Hugo's BaseURL. # See https://developer.mozilla.org/de/docs/Web/HTML/Element/base. geekdocOverwriteHTMLBase: false # (Optional, default true) Enable or disable the JavaScript based color theme toggle switch. The CSS based # user preference mode still works. geekdocDarkModeToggle: false # (Optional, default false) Auto-decrease brightness of images and add a slightly grayscale to avoid # bright spots while using the dark mode. geekdocDarkModeDim: false # (Optional, default false) Enforce code blocks to always use the dark color theme. geekdocDarkModeCode: false # (Optional, default true) Display a "Back to top" link in the site footer. geekdocBackToTop: true # (Optional, default false) Enable or disable adding tags for post pages automatically to the navigation sidebar. geekdocTagsToMenu: true # (Optional, default 'title') Configure how to sort file-tree menu entries. Possible options are 'title', 'linktitle', # 'date', 'publishdate', 'expirydate' or 'lastmod'. Every option can be used with a reverse modifier as well # e.g. 'title_reverse'. geekdocFileTreeSortBy: "title" # (Optional, default none) Adds a "Content licensed under " line to the footer. # Could be used if you want to define a default license for your content. geekdocContentLicense: name: CC BY-SA 4.0 link: https://creativecommons.org/licenses/by-sa/4.0/ ``` {{< /tab >}} {{< /tabs >}} ## Page configuration {{< tabs "page-config" >}} {{< tab "TOML" >}} ```toml # Set type to 'posts' if you want to render page as blogpost type = "posts" # Hugo predefined front matter variable, to re-arrange items in file-tree menu # See weights section of # https://gohugo.io/content-management/front-matter/#predefined weight = 10 # Set how many table of contents levels to be showed on page. geekdocToC = 3 # Set a description for the current page. This will be shown in toc-trees objects. geekdocDescription = # Set false to hide the whole left navigation sidebar. Beware that it will make # navigation pretty hard without adding some kind of on-page navigation. geekdocNav = true # Show a breadcrumb navigation bar at the top of each docs page. geekdocBreadcrumb = false # Set source repository location. geekdocRepo = "https://github.com/thegeeklab/hugo-geekdoc" # Enable 'Edit page' links. Requires 'geekdocRepo' param and the path must point to # the parent directory of the 'content' folder. geekdocEditPath = "edit/main/exampleSite" # Show last modification date of the page in the header. geekdocPageLastmod = true # Used for 'Edit page' link, set to '.File.Path' by default. # Can be overwritten by a path relative to 'geekdocEditPath' geekdocFilePath = # Set to mark page as flat section (file-tree menu only). geekdocFlatSection = true # Set true to hide page or section from side menu (file-tree menu only). geekdocHidden = true # Set false to show this page as a file-tree menu entry when you want it to be hidden in the sidebar. # NOTE: Only applies when 'geekdocHidden = true'. geekdocHiddenTocTree = true # Set to true to make a section foldable in side menu. geekdocCollapseSection = true # Add an anchor link to headlines. geekdocAnchor = true # If you have protected some pages with e.g. basic authentication you may want to exclude these pages # from data file, otherwise, information may be leaked. Setting this parameter to 'true' will exclude the # page from search data, feeds, etc. # WARNING: Consider hosting a standalone, fully auth-protected static page for secret information instead! geekdocProtected = false # Set 'left' (default), 'center' or 'right' to configure the text align of a page. geekdocAlign = "left" ``` {{< /tab >}} {{< tab "YAML" >}} ```yaml # Set type to 'posts' if you want to render page as blogpost. type: "posts" # Set page weight to re-arrange items in file-tree menu. weight: 10 # Set how many table of contents levels to be showed on page. geekdocToC: 3 # Set a description for the current page. This will be shown in toc-trees objects. geekdocDescription: # Set false to hide the whole left navigation sidebar. Beware that it will make # navigation pretty hard without adding some kind of on-page navigation. geekdocNav: true # Show a breadcrumb navigation bar at the top of each docs page. geekdocBreadcrumb: false # Set source repository location. geekdocRepo: "https://github.com/thegeeklab/hugo-geekdoc" # Enable 'Edit page' links. Requires 'geekdocRepo' param and the path must point to # the parent directory of the 'content' folder. geekdocEditPath: "edit/main/exampleSite" # Show last modification date of the page in the header. geekdocPageLastmod: true # Used for 'Edit page' link, set to '.File.Path' by default. # Can be overwritten by a path relative to 'geekdocEditPath' geekdocFilePath: # Set to mark page as flat section (file-tree menu only). geekdocFlatSection: true # Set true to hide page or section from side menu (file-tree menu only). geekdocHidden: true # Set false to show this page as a file-tree menu entry when you want it to be hidden in the sidebar. # NOTE: Only applies when 'geekdocHidden: true'. geekdocHiddenTocTree: true # Set to true to make a section foldable in side menu. geekdocCollapseSection: true # Add an anchor link to headlines. geekdocAnchor: true # If you have protected some pages with e.g. basic authentication you may want to exclude these pages # from data file, otherwise, information may be leaked. Setting this parameter to 'true' will exclude the # page from search data, feeds, etc. # WARNING: Consider hosting a standalone, fully auth-protected static page for secret information instead! geekdocProtected: false # Set 'left' (default), 'center' or 'right' to configure the text align of a page. geekdocAlign: "left" ``` {{< /tab >}} {{< /tabs >}} ================================================ FILE: exampleSite/content/en/usage/customization.md ================================================ --- title: Customization --- {{< toc >}} ## Custom resources To add custom resources to your site e.g. CSS or JavaScript files, create the `layouts/partials/head/custom.html` in the root directory of your project. Add the source files you want to include in the `static/` folder of your project, for example `static/css/custom.css` and `static/js/custom.js`. To include the files in your site, add the following code to `layouts/partials/head/custom.html`: ```html ``` Ensure to use the absolute path to the files. ================================================ FILE: exampleSite/content/en/usage/getting-started.md ================================================ --- title: Getting Started weight: -20 # cspell:ignore demosite testlink gohugoio --- This page tells you how to get started with the Geekdoc theme, including installation and basic configuration. {{< toc >}} ## Install requirements You need a recent version of Hugo for local builds and previews of sites that use Geekdoc. As we are using [webpack](https://webpack.js.org/) as pre-processor, the normal version of Hugo is sufficient. If you prefer the extended version of Hugo anyway this will work as well. For comprehensive Hugo documentation, see [gohugo.io](https://gohugo.io/documentation/). If you want to use the theme from a cloned branch instead of a release tarball you'll need to install `webpack` locally and run the build script once to create all required assets. ```shell # install required packages from package.json npm install # run the build script to build required assets npm run build # build release tarball npm run pack ``` ## Using the theme To prepare your new site environment just a few steps are required: 1. Create a new empty Hugo site. ```shell hugo new site demosite ``` 2. Switch to the root of the new site. ```shell cd demosite ``` 3. Install the Geekdoc theme from a [release bundle](#option-1-download-pre-build-release-bundle) (recommended) or from [Git branch](#option-2-clone-the-github-repository). 4. Create the minimal required Hugo configuration `hugo.toml`. For all configuration options take a look at the [configuration page](/usage/configuration/). ```toml baseURL = "http://localhost" title = "Geekdocs" theme = "hugo-geekdoc" pluralizeListTitles = false # Geekdoc required configuration pygmentsUseClasses = true pygmentsCodeFences = true disablePathToLower = true # Required if you want to render robots.txt template enableRobotsTXT = true # Needed for mermaid shortcodes [markup] [markup.goldmark.renderer] # Needed for mermaid shortcode or when nesting shortcodes (e.g. img within # columns or tabs) unsafe = true [markup.tableOfContents] startLevel = 1 endLevel = 9 [taxonomies] tag = "tags" ``` 5. Test your site. ```shell hugo server -D ``` The `-D` or `--buildDrafts` option is used to include content marked as draft during the build. It is used because content pages created with the `hugo new content` command have the `draft` flag set by default and this can lead to build errors in newly created projects. For projects with a production-ready content structure, this flag is not required in most cases and can be omitted. ### Option 1: Download pre-build release bundle Download and extract the latest release bundle into the theme directory. ```shell mkdir -p themes/hugo-geekdoc/ curl -L https://github.com/thegeeklab/hugo-geekdoc/releases/latest/download/hugo-geekdoc.tar.gz | tar -xz -C themes/hugo-geekdoc/ --strip-components=1 ``` ### Option 2: Clone the GitHub repository {{< hint type=note >}} Keep in mind this method is not recommended and needs some extra steps to get it working. If you want to use the Theme as submodule keep in mind that your build process need to run the described steps as well. {{< /hint >}} Clone the Geekdoc git repository. ```shell git clone https://github.com/thegeeklab/hugo-geekdoc.git themes/hugo-geekdoc ``` Build required theme assets e.g. CSS files and SVG sprites. ```shell npm install npm run build ``` ## Deployments ### Netlify There are several ways to deploy your site with this theme on Netlify. Regardless of which solution you choose, the main goal is to ensure that the prebuilt theme release tarball is used or to run the [required commands](#option-2-clone-the-github-repository) to prepare the theme assets before running the Hugo build command. Here are some possible solutions: #### Use a Makefile Add a Makefile to your repository to bundle the required steps. {{< hint type=important >}} The `Makefile` is only an example. Depending on your project structure, `BASEDIR` or `THEMEDIR` may need to be adapted. {{< /hint >}} ```makefile # Please change the theme version to the latest release version. THEME_VERSION := v0.44.1 THEME := hugo-geekdoc BASEDIR := docs THEMEDIR := $(BASEDIR)/themes .PHONY: doc doc: doc-assets doc-build .PHONY: doc-assets doc-assets: mkdir -p $(THEMEDIR)/$(THEME)/ ; \ curl -sSL "https://github.com/thegeeklab/$(THEME)/releases/download/${THEME_VERSION}/$(THEME).tar.gz" | tar -xz -C $(THEMEDIR)/$(THEME)/ --strip-components=1 .PHONY: doc-build doc-build: cd $(BASEDIR); hugo .PHONY: clean clean: rm -rf $(THEMEDIR) && \ rm -rf $(BASEDIR)/public ``` This Makefile can be used in your `netlify.toml`, take a look at the [Netlify example](https://docs.netlify.com/configure-builds/file-based-configuration/#sample-netlify-toml-file) for more information: ```toml [build] publish = "docs/public" command = "make doc" ``` #### Chain required commands Chain all required commands to prepare the theme and build your site on the `command` option in your `netlify.toml` like this: ```toml [build] publish = "docs/public" command = "command1 && command 2 && command3 && hugo" ``` ### Subdirectories {{< hint type=important >}} As deploying Hugo sites on subdirectories is not as robust as on subdomains, we do not recommend this. If you have a choice, using a domain/subdomain should always be the preferred solution! {{< /hint >}} If you want to deploy your site to a subdirectory of your domain, some extra steps are required: - Configure your Hugo base URL e.g. `baseURL = http://localhost/demo/`. - Don't use `relativeURLs: false` nor `canonifyURLs: true` as is can cause unwanted side effects! There are two ways to get Markdown links or images working: - Use the absolute path including your subdirectory e.g. `[testlink](/demo/example-site)` - Overwrite the HTML base in your site configuration with `geekdocOverwriteHTMLBase = true` and use the relative path e.g. `[testlink](example-site)` But there is another special case if you use `geekdocOverwriteHTMLBase = true`. If you use anchors in your Markdown links you have to ensure to always include the page path. As an example `[testlink](#some-anchor)` will resolve to `http://localhost/demo/#some-anchor` and not automatically include the current page! ## Known Limitations ### Minify HTML results in spacing issues Using `hugo --minify` without further configuration or using other minify tools that also minify HTML files might result in spacing issues in the theme and is **not** supported. After some testing we decided to not spend effort to fix this issue for now as the benefit is very low. There are some parts of the theme where spaces between HTML elements matters but were stripped by minify tools. Some of these issues are related to [gohugoio/hugo#6892](https://github.com/gohugoio/hugo/issues/6892). While recommendation like "don't depend on whitespace in your layout" sounds reasonable, it seems to be not that straight forward especially for something like embedded icons into the text flow. If you still want to use Hugo's minify flag you should at least exclude HTML files in your site configuration as described in the [Hugo documentation](https://gohugo.io/getting-started/configuration/#configure-minify): ```toml [minify] disableHTML = true ``` ================================================ FILE: exampleSite/content/en/usage/menus.md ================================================ --- title: Menus --- The theme supports two different kinds of menus. File-tree menu is the default one and does not require further configuration to work. If you want full control about your menu the bundle menu is a powerful option to accomplish it. {{< toc >}} ## File-tree menu As the name already suggests, the file tree menu builds a menu from the file system structure of the content folder. By default, areas and subareas are sorted alphabetically by the title of the pages. To manipulate the order the `weight` parameter in a page [front matter](https://gohugo.io/content-management/front-matter/) can be used. To structure your content folder you have to use [page bundles](https://gohugo.io/content-management/organization/#page-bundles), single files are **not** supported. Hugo will render build single files in the content folder just fine but it will not be added to the menu. **Example:** File system structure: ```plain content/ ├── level-1 │   ├── _index.md │   ├── level-1-1.md │   ├── level-1-2.md │   └── level-1-3 │   ├── _index.md │   └── level-1-3-1.md └── level-2 ├── _index.md ├── level-2-1.md └── level-2-2.md ``` ## Bundle menu This type of navigation needs to be enabled first by setting `geekdocMenuBundle` to `true` in your [site configuration](/usage/configuration/#site-configuration). After you have activated the bundle menu, you start with an empty navigation. This is intentional because bundle menus have to be defined manually in a data file. While this increases the effort it also offers maximum flexibility in the design. The data file needs to be written in YAML and placed at `data/menu/main.yaml`. **Example:** ```yaml --- main: - name: Level 1 ref: "/level-1" icon: "gdoc_notification" sub: - name: Level 1.1 ref: "/level-1/level-1-1" - name: Level 1.2 ref: "/level-1/level-1-2" - name: Level 1.3 ref: "/level-1/level-1-3" sub: - name: Level 1.3.1 ref: "/level-1/level-1-3/level-1-3-1" - name: Level 2 ref: "/level-2" sub: - name: Level 2.1 ref: "/level-2/level-2-1" - name: Level 2.2 ref: "/level-2/level-2-2" - name: Level 2.2 Anchor ref: /level-2/level-2-2 # Anchor to add to the entry. This example will result in `/level-2/level-2-2/#anchor` anchor: anchor ``` As an advantage you can add [icons](/features/icon-sets/) to your menu entries e.g. `icon: "gdoc_notification"`. ### More menu {{< hint type=tip >}} **Tip**\ The more menu is special type of the bundle menu and can be combined with the default file-tree menu. {{< /hint >}} As this is a special type of the bundle menu it is basically working in the same way. To enable it just add a data file to `data/menu/more.yaml`. The more menu will also work with the file-tree menu and therefore **don't need to be enabled** by the `geekdocMenuBundle` parameter. **Example:** ```yaml --- more: - name: News ref: "/#" icon: "gdoc_notification" - name: Releases ref: "https://github.com/thegeeklab/hugo-geekdoc/releases" external: true icon: "gdoc_download" - name: "View Source" ref: "https://github.com/thegeeklab/hugo-geekdoc" external: true icon: "gdoc_github" ``` ## Extra Header Menu If you want to customize the header menu, this can be achieved by using a data file written in YAML and placed at `data/menu/extra.yaml`. **Example:** ```yaml --- header: - name: GitHub ref: https://github.com/thegeeklab/hugo-geekdoc icon: gdoc_github external: true ``` ================================================ FILE: exampleSite/data/menu/extra.yaml ================================================ --- header: - name: GitHub ref: https://github.com/thegeeklab/hugo-geekdoc icon: gdoc_github external: true ================================================ FILE: exampleSite/data/menu/main.yaml ================================================ --- main: - name: en: Level 1 (EN) de: Level 1 (DE) sub: - name: en: Level 1.1 (EN) de: Level 1.1 (DE) ref: "/toc-tree/level-1/level-1-1" rel: me - name: Level 1.2 ref: "/toc-tree/level-1/level-1-2" - name: Level 1.3 ref: "/toc-tree/level-1/level-1-3" sub: - name: Level 1.3.1 ref: "/toc-tree/level-1/level-1-3/level-1-3-1" - name: Level 2 ref: "/toc-tree/level-2" sub: - name: Level 2.1 ref: "/toc-tree/level-2/level-2-1" - name: Level 2.2 ref: "/toc-tree/level-2/level-2-2" ================================================ FILE: exampleSite/data/menu/more.yaml ================================================ --- more: - name: News ref: "/posts" icon: "gdoc_notification" - name: Releases ref: "https://github.com/thegeeklab/hugo-geekdoc/releases" external: true icon: "gdoc_download" - name: View Source ref: "https://github.com/thegeeklab/hugo-geekdoc" external: true icon: "gdoc_github" ================================================ FILE: exampleSite/data/properties/demo.yaml ================================================ --- properties: - name: prop1 type: string description: Dummy description of the prop1 string property. required: true - name: prop2 type: int defaultValue: 10 description: en: Another description for the integer property called prop2. required: false tags: en: - tag1 - tag2 - name: prop3 type: bool defaultValue: false description: | A `bool` property with a complex multiline description and embedded Markdown: - List item 1 - List item 2 More description how to use this property. required: false - name: a-prop type: string description: Property to demonstrate sorting. required: true ================================================ FILE: exampleSite/data/properties/shortcode-audio.yaml ================================================ --- properties: - name: name type: string description: Name of the audio resource defined in page front matter. required: true ================================================ FILE: exampleSite/data/properties/shortcode-avatar.yaml ================================================ --- properties: - name: name type: string description: Name of the image resource defined in page front matter. required: true - name: alt type: string description: Description text for the image. required: false - name: size type: string description: Thumbnail size. Supported values are `origin|tiny|small|medium|large`. required: false - name: anchor type: string description: "[Anchor](https://gohugo.io/content-management/image-processing/#anchor) to determine the placement of the crop box." required: false ================================================ FILE: exampleSite/data/properties/shortcode-buttons.yaml ================================================ --- properties: - name: href type: string description: The URL to use as target of the button. required: false - name: relref type: string description: Executes the [relref](https://gohugo.io/functions/urls/relref/) Hugo function to resolve the relative permalink of the specified page. The result is set as the target of the button. required: false - name: class type: list description: List of space-separated CSS class names to apply. required: false - name: size type: string description: Preset of different button sizes. Supported values are `regular|large`. required: false defaultValue: regular ================================================ FILE: exampleSite/data/properties/shortcode-columns.yaml ================================================ --- properties: - name: size type: string description: Preset of different sizes for the _first_ column. Supported values are `small|regular|large`. required: false defaultValue: regular ================================================ FILE: exampleSite/data/properties/shortcode-hints.yaml ================================================ --- properties: - name: type type: string description: Type of the hint. Supported values are `note|tip|important|caution|warning`. required: false defaultValue: note - name: icon type: string description: Icon to use. The value need to be an icon from an [SVG sprite](/features/icon-sets/). required: false - name: title type: string description: Title text of the hint. required: false ================================================ FILE: exampleSite/data/properties/shortcode-images.yaml ================================================ --- properties: - name: name type: string description: Name of the image resource defined in page front matter. required: true - name: alt type: string description: Description text for the image. required: false - name: size type: string description: Thumbnail size. Supported values are `origin|tiny|small|medium|large`. required: false - name: lazy type: bool description: Enable/disable lazy loading for the image. required: false defaultValue: true ================================================ FILE: exampleSite/data/properties/shortcode-includes.yaml ================================================ --- properties: - name: file type: string description: Path of the file (relative to the Hugo root) to include. required: true - name: language type: string description: Language for [syntax highlighting](https://gohugo.io/content-management/syntax-highlighting/#list-of-chroma-highlighting-languages). required: false - name: type type: string description: Special include type. Supported values are `html|page`. If not set the included file is rendered as markdown. required: false - name: options type: bool description: highlighting [options](https://gohugo.io/content-management/syntax-highlighting/#highlight-shortcode). required: false defaultValue: linenos=table ================================================ FILE: exampleSite/data/properties/shortcode-katex.yaml ================================================ --- properties: - name: class type: list description: List of space-separated CSS class names to apply. required: false ================================================ FILE: exampleSite/data/properties/shortcode-mermaid.yaml ================================================ --- properties: - name: class type: list description: List of space-separated CSS class names to apply. required: false ================================================ FILE: exampleSite/data/properties/shortcode-progress.yaml ================================================ --- properties: - name: type type: string description: Color type of the progress bar. Supported values are `main|note|tip|important|caution|warning`. required: false defaultValue: main - name: value type: integer description: Progress value. required: false defaultValue: 0 - name: label type: string description: Value to display. required: false defaultValue: "`value`" - name: icon type: string description: Icon to use. The value need to be an icon from an [SVG sprite](/features/icon-sets/). required: false - name: title type: string description: Title text of the progress bar. required: false ================================================ FILE: exampleSite/data/properties/shortcode-propertylist.yaml ================================================ --- properties: - name: name type: string description: Name of the file from the `data/properties/` directory. required: true - name: sort type: string description: Field name to use for sorting. required: false - name: order type: string description: Sort order, only applied if `sort` is set. Supported values are `asc|desc`. required: false defaultValue: asc ================================================ FILE: exampleSite/data/properties/shortcode-toc-tree.yaml ================================================ --- properties: - name: sortBy type: string description: | Override the default sort parameter set by [`geekdocFileTreeSortBy`](/usage/configuration/#site-configuration). required: false defaultValue: .Site.Params.geekdocFileTreeSortBy ================================================ FILE: exampleSite/data/properties/shortcode-toc.yaml ================================================ --- properties: - name: format type: string description: | Format of the returned ToC. The `html` format creates an HTML wrapper to enable the `geekdocToC` parameter that limits the maximum ToC level to be displayed. This variant also automatically inserts a horizontal line after the ToC. The `raw` format returns the unformatted ToC, the parameter `geekdocToC` does not work in this mode. Supported values are `html|raw`. required: false defaultValue: html ================================================ FILE: exampleSite/layouts/shortcodes/sprites.html ================================================
{{ range $key, $value := hugo.Data.sprites.geekdoc }}
#{{ (replace $key "_" "_") | safeHTML }}
{{ end }}
================================================ FILE: exampleSite/static/.htaccess ================================================ ErrorDocument 404 /404.html ExpiresActive On ExpiresDefault "access plus 600 seconds" ExpiresByType text/css "access plus 1 week" ExpiresByType text/javascript "access plus 1 month" ExpiresByType text/html "access plus 1 seconds" ExpiresByType application/javascript "access plus 1 month" ExpiresByType application/x-javascript "access plus 1 month" ExpiresByType image/gif "access plus 1 week" ExpiresByType image/jpeg "access plus 1 week" ExpiresByType image/png "access plus 1 week" ExpiresByType image/x-icon "access plus 1 month" ExpiresByType image/svg+xml "access plus 1 week" ExpiresByType application/x-font-woff "access plus 1 week" ExpiresByType application/font-woff2 "access plus 1 week" ================================================ FILE: exampleSite/static/_includes/example.html.part ================================================

Example HTML include

This is heading 4

This is heading 5
This is heading 6
================================================ FILE: exampleSite/static/_includes/example.md.part ================================================ _**Example Markdown include**_ File including a simple Markdown table. | Head 1 | Head 2 | Head 3 | | ------ | ------ | ------ | | 1 | 2 | 3 | ================================================ FILE: exampleSite/static/custom.css ================================================ :root { --code-max-height: 60rem; } .icon-grid { width: 8rem; height: 8rem; margin: 0.2em; text-align: center; padding: 0.3em; } .icon-grid__line { height: 4rem; } .icon-grid__line .gdoc-icon { width: 3em; height: 3em; } .icon-grid__line--text { font-size: 0.8em; } ================================================ FILE: exampleSite/static/custom.css.example ================================================ /* Global customization */ :root { --code-max-height: 60rem; --header-font-family: "DancingScript"; --body-font-family: "DancingScript"; --code-font-family: "DancingScript"; } /* Light mode theming */ :root, :root[color-theme="light"] { --header-background: #4ec58a; --header-font-color: #ffffff; --body-background: #ffffff; --body-font-color: #343a40; --mark-color: #ffab00; --button-background: #62cb97; --button-border-color: #4ec58a; --link-color: #518169; --link-color-visited: #c54e8a; --code-background: #f5f6f8; --code-accent-color: #e3e7eb; --code-accent-color-lite: #eff1f3; --code-font-color: #5f5f5f; --code-copy-background: #f5f6f8; --code-copy-font-color: #6b7784; --code-copy-border-color: #adb4bc; --code-copy-success-color: #00c853; --accent-color: #e9ecef; --accent-color-lite: #f8f9fa; --control-icons: #b2bac1; --footer-background: #112b3c; --footer-font-color: #ffffff; --footer-link-color: #ffcc5c; --footer-link-color-visited: #ffcc5c; } @media (prefers-color-scheme: light) { :root { --header-background: #4ec58a; --header-font-color: #ffffff; --body-background: #ffffff; --body-font-color: #343a40; --mark-color: #ffab00; --button-background: #62cb97; --button-border-color: #4ec58a; --link-color: #518169; --link-color-visited: #c54e8a; --code-background: #f5f6f8; --code-accent-color: #e3e7eb; --code-accent-color-lite: #eff1f3; --code-font-color: #5f5f5f; --code-copy-background: #f5f6f8; --code-copy-font-color: #6b7784; --code-copy-border-color: #adb4bc; --code-copy-success-color: #00c853; --accent-color: #e9ecef; --accent-color-lite: #f8f9fa; --control-icons: #b2bac1; --footer-background: #112b3c; --footer-font-color: #ffffff; --footer-link-color: #ffcc5c; --footer-link-color-visited: #ffcc5c; } } /* Dark mode theming */ :root[color-theme="dark"] { --header-background: #4ec58a; --header-font-color: #ffffff; --body-background: #343a40; --body-font-color: #ced3d8; --mark-color: #ffab00; --button-background: #62cb97; --button-border-color: #4ec58a; --link-color: #7ac29e; --link-color-visited: #c27a9e; --code-background: #2f353a; --code-accent-color: #262b2f; --code-accent-color-lite: #2b3035; --code-font-color: #b9b9b9; --code-copy-background: #343a40; --code-copy-font-color: #6b7784; --code-copy-border-color: #6b7784; --code-copy-success-color: #37905c; --accent-color: #2b3035; --accent-color-lite: #2f353a; --control-icons: #b2bac1; --footer-background: #112b3c; --footer-font-color: #ffffff; --footer-link-color: #ffcc5c; --footer-link-color-visited: #ffcc5c; } @media (prefers-color-scheme: dark) { :root { --header-background: #4ec58a; --header-font-color: #ffffff; --body-background: #343a40; --body-font-color: #ced3d8; --mark-color: #ffab00; --button-background: #62cb97; --button-border-color: #4ec58a; --link-color: #7ac29e; --link-color-visited: #c27a9e; --code-background: #2f353a; --code-accent-color: #262b2f; --code-accent-color-lite: #2b3035; --code-font-color: #b9b9b9; --code-copy-background: #343a40; --code-copy-font-color: #6b7784; --code-copy-border-color: #6b7784; --code-copy-success-color: #37905c; --accent-color: #2b3035; --accent-color-lite: #2f353a; --control-icons: #b2bac1; --footer-background: #112b3c; --footer-font-color: #ffffff; --footer-link-color: #ffcc5c; --footer-link-color-visited: #ffcc5c; } } @font-face { font-family: "DancingScript"; src: url("fonts/DancingScript.woff2") format("woff2"), url("fonts/DancingScript.woff") format("woff"); font-weight: normal; font-style: normal; font-display: swap; } ================================================ FILE: i18n/am.yaml ================================================ --- edit_page: ገጹን ማስተካከያ nav_navigation: መሄጃ nav_tags: መለያዎች nav_more: ተጨማሪ nav_top: ወደ ላይ ተመለስ form_placeholder_search: ፈልግ error_page_title: ጠፋብዎት? አይጨነቁ። error_message_title: ጠፋብዎት? error_message_code: አልተገኘም error_message_text: > ገጹን ማግኘት አልተቻለም፤ ነገር ግን አይጨነቁ፤ በዚህ ገጽ መመለስ ይችላሉ። button_toggle_dark: ብሩህ/ጨለማ መቀያየሪያ button_nav_open: መሄጃውን ክፈት button_nav_close: መሄጃውን ዝጋ button_menu_open: ምርጫዎችን ክፈት button_menu_close: ምርጫዎችን ዝጋ button_homepage: ወደ መጀመሪያ ገጽ ተመለስ title_anchor_prefix: "ማያያዣ ወደ:" posts_read_more: ሙሉውን ያንብቡ posts_read_time: one: "ለማንበብ አንድ ደቂቃ" other: "{{ . }} ደቂቃዎች ለማንበብ" posts_update_prefix: መጨረሻ የዘመነው posts_count: one: "አንድ ጽሑፍ" other: "{{ . }} ጽሑፎች" posts_tagged_with: ከ '{{ . }}' ጋር የተዛመዱ ጽሑፎች በሙሉ footer_build_with: > በ Hugo የተገነባ ከ ጋር footer_legal_notice: ሕጋዊ መረጃዎች footer_privacy_policy: ስለ መረጃዎ አያያዝ ያለን አቋም footer_content_license_prefix: > ስለ ይዘቱ ባለመብትነት መረጃ language_switch_no_translation_prefix: "ያልተተረጐመ ገጽ:" propertylist_required: ግድ የሚያስፈልግ propertylist_optional: ግድ ያልሆነ propertylist_default: በባዶ ፈንታ pagination_page_prev: ያለፈው pagination_page_next: ቀጣይ pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: i18n/cs.yaml ================================================ --- edit_page: Upravit stránku nav_navigation: Navigace nav_tags: Tagy nav_more: Více nav_top: Zpět nahoru form_placeholder_search: Vyhledat error_page_title: Ztracen? Nic se neděje error_message_title: Ztracen? error_message_code: Error 404 error_message_text: > Vypadá to že stránka, kterou hledáte, neexistuje. Nemějte obavy, můžete se vrátit zpět na domovskou stránku. button_toggle_dark: Přepnout tmavý/světlý/automatický režim button_nav_open: Otevřít navigaci button_nav_close: Zavřít navigaci button_menu_open: Otevřít lištu nabídky button_menu_close: Zavřít lištu nabídky button_homepage: Zpět na domovskou stránku title_anchor_prefix: "Odkaz na:" posts_read_more: Přečíst celý příspěvek posts_read_time: one: "Doba čtení: 1 minuta" other: "Doba čtení: {{ . }} minut(y)" posts_update_prefix: Naposledy upraveno posts_count: one: "Jeden příspěvek" other: "Příspěvků: {{ . }}" posts_tagged_with: Všechny příspěvky označeny '{{ . }}' footer_build_with: > Vytvořeno za pomocí Hugo a footer_legal_notice: Právní upozornění footer_privacy_policy: Zásady ochrany soukromí footer_content_license_prefix: > Obsah licencovaný pod language_switch_no_translation_prefix: "Stránka není přeložena:" propertylist_required: povinné propertylist_optional: volitené propertylist_default: výchozí pagination_page_prev: předchozí pagination_page_next: další pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: i18n/da.yaml ================================================ --- edit_page: Rediger side nav_navigation: Navigation nav_tags: Tags nav_more: Mere nav_top: Til toppen form_placeholder_search: Søg error_page_title: Faret vild? Bare rolig error_message_title: Lost? error_message_code: Fejl 404 error_message_text: > Det du leder efter kan ikke findes. Bare rolig, du kan komme tilbage til forsiden. button_toggle_dark: Skift Dark/Light/Auto mode button_nav_open: Åben navigation button_nav_close: Luk navigation button_menu_open: Åben menubar button_menu_close: Luk menubar button_homepage: Tilbage til forsiden title_anchor_prefix: "Link til:" posts_read_more: Læs fulde indlæg posts_read_time: one: "Et minut at gennemlæse" other: "{{ . }} minutter at gennemlæse" posts_update_prefix: Opdateret den posts_count: one: "Et indlæg" other: "{{ . }} indlæg" posts_tagged_with: Alle indslag tagget med '{{ . }}' footer_build_with: > Bygget med Hugo og footer_legal_notice: Forretningsbetingelser footer_privacy_policy: Privatlivspolitik footer_content_license_prefix: > Indhold licenseret under language_switch_no_translation_prefix: "Indlæg ikke oversat:" propertylist_required: påkrævet propertylist_optional: valgfri propertylist_default: udgangspunkt pagination_page_prev: forrige pagination_page_next: næste pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: i18n/de.yaml ================================================ --- edit_page: Seite bearbeiten nav_navigation: Navigation nav_tags: Tags nav_more: Weitere nav_top: Nach oben form_placeholder_search: Suchen error_page_title: Verlaufen? Keine Sorge error_message_title: Verlaufen? error_message_code: Fehler 404 error_message_text: > Wir können die Seite nach der Du gesucht hast leider nicht finden. Keine Sorge, wir bringen Dich zurück zur Startseite. button_toggle_dark: Wechsel zwischen Dunkel/Hell/Auto Modus button_nav_open: Navigation öffnen button_nav_close: Navigation schließen button_menu_open: Menüband öffnen button_menu_close: Menüband schließen button_homepage: Zurück zur Startseite title_anchor_prefix: "Link zu:" posts_read_more: Ganzen Artikel lesen posts_read_time: one: "Eine Minute Lesedauer" other: "{{ . }} Minuten Lesedauer" posts_update_prefix: Aktualisiert am posts_count: one: "Ein Artikel" other: "{{ . }} Artikel" posts_tagged_with: Alle Artikel mit dem Tag '{{ . }}' footer_build_with: > Entwickelt mit Hugo und footer_legal_notice: Impressum footer_privacy_policy: Datenschutzerklärung footer_content_license_prefix: > Inhalt lizensiert unter language_switch_no_translation_prefix: "Seite nicht übersetzt:" propertylist_required: erforderlich propertylist_optional: optional propertylist_default: Standardwert pagination_page_prev: vorher pagination_page_next: weiter pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: i18n/en.yaml ================================================ --- edit_page: Edit page nav_navigation: Navigation nav_tags: Tags nav_more: More nav_top: Back to top form_placeholder_search: Search error_page_title: Lost? Don't worry error_message_title: Lost? error_message_code: Error 404 error_message_text: > Seems like what you are looking for can't be found. Don't worry, we can bring you back to the homepage. button_toggle_dark: Toggle Dark/Light/Auto mode button_nav_open: Open Navigation button_nav_close: Close Navigation button_menu_open: Open Menu Bar button_menu_close: Close Menu Bar button_homepage: Back to homepage title_anchor_prefix: "Anchor to:" posts_read_more: Read full post posts_read_time: one: "One minute to read" other: "{{ . }} minutes to read" posts_update_prefix: Updated on posts_count: one: "One post" other: "{{ . }} posts" posts_tagged_with: All posts tagged with '{{ . }}' footer_build_with: > Built with Hugo and footer_legal_notice: Legal Notice footer_privacy_policy: Privacy Policy footer_content_license_prefix: > Content licensed under language_switch_no_translation_prefix: "Page not translated:" propertylist_required: required propertylist_optional: optional propertylist_default: default pagination_page_prev: prev pagination_page_next: next pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: i18n/es.yaml ================================================ --- edit_page: Editar página nav_navigation: Navegación nav_tags: Etiquetas nav_more: Más nav_top: Inicio de la página form_placeholder_search: Buscar error_page_title: Perdido? No te preocupes error_message_title: Perdido? error_message_code: Error 404 error_message_text: > Al parecer, lo que estás buscando no pudo ser encontrado. No te preocupes, podemos llevarte de vuelta al inicio. button_toggle_dark: Cambiar el modo Oscuro/Claro/Auto button_nav_open: Abrir la Navegación button_nav_close: Cerrar la Navegación button_menu_open: Abrir el Menú Bar button_menu_close: Cerrar el Menú Bar button_homepage: Volver al Inicio title_anchor_prefix: "Anclado a:" posts_read_more: Lee la publicación completa posts_read_time: one: "Un minuto para leer" other: "{{ . }} minutos para leer" posts_update_prefix: Actualizado en posts_count: one: "Una publicación" other: "{{ . }} publicaciones" posts_tagged_with: Todas las publicaciones etiquetadas con '{{ . }}' footer_build_with: > Creado con Hugo y footer_legal_notice: Aviso Legal footer_privacy_policy: Política de Privacidad footer_content_license_prefix: > Contenido licenciado con language_switch_no_translation_prefix: "Página no traducida:" propertylist_required: requerido propertylist_optional: opcional propertylist_default: estándar pagination_page_prev: previo pagination_page_next: siguiente pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: i18n/fr.yaml ================================================ --- edit_page: Editer la page nav_navigation: Navigation nav_tags: Tags nav_more: Plus nav_top: Retour au haut de page form_placeholder_search: Chercher error_page_title: Perdu? Ne t'inquiète pas error_message_title: Perdu? error_message_code: Error 404 error_message_text: > On dirait que ce que vous cherchez est introuvable. Ne vous inquiétez pas, nous pouvons vous ramèner à la page d'accueil. button_toggle_dark: Basculer le mode Sombre/Clair/Auto button_nav_open: Ouvrir la navigation button_nav_close: Fermer la navigation button_menu_open: Ouvrir la barre de menus button_menu_close: Fermer la barre de menus button_homepage: retour à la page d'accueil title_anchor_prefix: "Ancrer à :" posts_read_more: Lire l'article complet posts_read_time: one: "Une minute pour lire" other: "{{ . }} minutes à lire" posts_update_prefix: Mis à jour le posts_count: one: "Un billet" other: "{{ . }} billets" posts_tagged_with: Tous les articles marqués avec '{{ . }}' footer_build_with: > Construit avec Hugo et footer_legal_notice: Mentions légales footer_privacy_policy: Politique de confidentialité footer_content_license_prefix: > Contenu sous licence language_switch_no_translation_prefix: "Page non traduite:" propertylist_required: requis propertylist_optional: facultatif propertylist_default: défaut pagination_page_prev: précédent pagination_page_next: suivant pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: i18n/it.yaml ================================================ --- edit_page: Modifica la pagina nav_navigation: Navigazione nav_tags: Etichette nav_more: Altro nav_top: Torna su form_placeholder_search: Cerca error_page_title: Perso? Non ti preoccupare error_message_title: Perso? error_message_code: Errore 404 error_message_text: > Sembra che non sia possibile trovare quello che stavi cercando. Non ti preoccupare, possiamo riportarti alla pagina iniziale. button_toggle_dark: Seleziona il tema Chiaro/Scuro/Automatico button_nav_open: Apri la Navigazione button_nav_close: Chiudi la Navigazione button_menu_open: Apri la Barra del Menu button_menu_close: Chiudi la Barra del Menu button_homepage: Torna alla pagina iniziale title_anchor_prefix: "Ancora a:" posts_read_more: Leggi tutto il post posts_read_time: one: "Tempo di lettura: un minuto" other: "Tempo di lettura: {{ . }} minuti" posts_update_prefix: Aggiornato il posts_count: one: "Un post" other: "{{ . }} post" posts_tagged_with: Tutti i post etichettati con '{{ . }}' footer_build_with: > Realizzato con Hugo e footer_legal_notice: Avviso Legale footer_privacy_policy: Politica sulla Privacy footer_content_license_prefix: > Contenuto sotto licenza language_switch_no_translation_prefix: "Pagina non tradotta:" propertylist_required: richiesto propertylist_optional: opzionale propertylist_default: valore predefinito pagination_page_prev: precedente pagination_page_next: prossimo pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: i18n/ja.yaml ================================================ --- edit_page: ページの編集 nav_navigation: ナビゲーション nav_tags: タグ nav_more: さらに nav_top: トップへ戻る form_placeholder_search: 検索 error_page_title: お困りですか?ご心配なく error_message_title: お困りですか? error_message_code: 404 エラー error_message_text: > お探しのものが見つからないようです。トップページ へ戻ることができるので、ご安心ください。 button_toggle_dark: モードの切替 ダーク/ライト/自動 button_nav_open: ナビゲーションを開く button_nav_close: ナビゲーションを閉じる button_menu_open: メニューバーを開く button_menu_close: メニューバーを閉じる button_homepage: トップページへ戻る title_anchor_prefix: "アンカー先:" posts_read_more: 全投稿を閲覧 posts_read_time: one: "読むのに 1 分かかります" other: "読むのに要する時間 {{ . }} (分)" posts_update_prefix: 更新時刻 posts_count: one: "一件の投稿" other: "{{ . }} 件の投稿" posts_tagged_with: "'{{ . }}'のタグが付いた記事全部" footer_build_with: > Hugo でビルドしています。 footer_legal_notice: 法的な告知事項 footer_privacy_policy: プライバシーポリシー footer_content_license_prefix: > 提供するコンテンツのライセンス language_switch_no_translation_prefix: "未翻訳のページ:" propertylist_required: 必須 propertylist_optional: 任意 propertylist_default: 既定値 pagination_page_prev: 前 pagination_page_next: 次 pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: i18n/nl.yaml ================================================ --- edit_page: Wijzig pagina nav_navigation: Navigatie nav_tags: Markering nav_more: Meer nav_top: Terug naar boven form_placeholder_search: Zoek error_page_title: Verdwaald? Geen probleem error_message_title: Verdwaald? error_message_code: Error 404 error_message_text: > Het lijkt er op dat wat je zoekt niet gevonden kan worden. Geen probleem, we kunnen je terug naar de startpagina brengen. button_toggle_dark: Wijzig Donker/Licht/Auto weergave button_nav_open: Open navigatie button_nav_close: Sluit navigatie button_menu_open: Open menubalk button_menu_close: Sluit menubalk button_homepage: Terug naar startpagina title_anchor_prefix: "Link naar:" posts_read_more: Lees volledige bericht posts_read_time: one: "Een minuut leestijd" other: "{{ . }} minuten leestijd" posts_update_prefix: Bijgewerkt op posts_count: one: "Een bericht" other: "{{ . }} berichten" posts_tagged_with: Alle berichten gemarkeerd met '{{ . }}' footer_build_with: > Gebouwd met Hugo en footer_legal_notice: Juridische mededeling footer_privacy_policy: Privacybeleid footer_content_license_prefix: > Inhoud gelicenseerd onder language_switch_no_translation_prefix: "Pagina niet vertaald:" propertylist_required: verplicht propertylist_optional: optioneel propertylist_default: standaard pagination_page_prev: vorige pagination_page_next: volgende pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: i18n/oc.yaml ================================================ --- edit_page: Modificar la pagina nav_navigation: Navegacion nav_tags: Etiquetas nav_more: Mai nav_top: Tornar ennaut form_placeholder_search: Cercar error_page_title: Perdut ? Cap de problèma error_message_title: Perdut ? error_message_code: Error 404 error_message_text: > Sembla que cercatz quicòm que se pòt pas trobat. Vos’n fagatz pas vos podèm tornar a la pagina d’acuèlh. button_toggle_dark: Alternar lo mòde escur/clar/auto button_nav_open: Dobrir la navegacion button_nav_close: Tampar la navegacion button_menu_open: Dobrir la barra de menú button_menu_close: Tampar la barra de menú button_homepage: Tornar a la pagina d’acuèlh title_anchor_prefix: "Ancorar a:" posts_read_more: Legir la publicacion complèta posts_read_time: one: "Una minuta de lectura" other: "{{ . }} minutas de lectura" posts_update_prefix: Actualizada lo posts_count: one: "Una publicacion" other: "{{ . }} publicacions" posts_tagged_with: Totas las publicacions amb '{{ . }}' footer_build_with: > Construch amb Hugo e footer_legal_notice: Mencions legalas footer_privacy_policy: politica de confidencialitat footer_content_license_prefix: > Contengut sota licéncia language_switch_no_translation_prefix: "Pagina non traducha :" propertylist_required: requerit propertylist_optional: opcional propertylist_default: per defaut pagination_page_prev: prec. pagination_page_next: seg. pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: i18n/zh-cn.yaml ================================================ --- edit_page: 编辑页面 nav_navigation: 导航 nav_tags: 标签 nav_more: 更多 nav_top: 回到顶部 form_placeholder_search: 搜索 error_page_title: 迷路了? 不用担心 error_message_title: 迷路了? error_message_code: 错误 404 error_message_text: > 好像找不到你要找的东西。 别担心,我们可以 带您回到主页。 button_toggle_dark: 切换暗/亮/自动模式 button_nav_open: 打开导航 button_nav_close: 关闭导航 button_menu_open: 打开菜单栏 button_menu_close: 关闭菜单栏 button_homepage: 返回首页 title_anchor_prefix: "锚定到:" posts_read_more: 阅读全文 posts_read_time: one: "一分钟阅读时间" other: "{{ . }} 分钟阅读时间" posts_update_prefix: 更新时间 posts_count: one: 一篇文章 other: "{{ . }} 个帖子" posts_tagged_with: 所有带有“{{ . }}”标签的帖子。 footer_build_with: > 基于 Hugo 制作 footer_legal_notice: "法律声明" footer_privacy_policy: "隐私政策" footer_content_license_prefix: > 内容许可证 language_switch_no_translation_prefix: "页面未翻译:" propertylist_required: 需要 propertylist_optional: 可选 propertylist_default: 默认值 pagination_page_prev: 以前 pagination_page_next: 下一个 pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" ================================================ FILE: layouts/404.html ================================================ {{ partial "head/meta" . }} {{ i18n "error_page_title" }} {{ partial "head/favicons" . }} {{ partial "head/others" . }} {{ partial "svg-icon-symbols" . }}
{{ partial "site-header" (dict "Root" . "MenuEnabled" false) }}
{{ i18n "error_message_title" }}
{{ i18n "error_message_code" }}
{{ i18n "error_message_text" .Site.Home.Permalink | safeHTML }}
{{ partial "site-footer" . }}
================================================ FILE: layouts/_default/_markup/render-codeblock-mermaid.html ================================================ {{ if not (.Page.Scratch.Get "mermaid") }} {{ .Page.Scratch.Set "mermaid" true }} {{ end }}
  {{- .Inner -}}
================================================ FILE: layouts/_default/_markup/render-heading.html ================================================ {{- $showAnchor := (and (default true .Page.Params.geekdocAnchor) (default true .Page.Site.Params.geekdocAnchor)) -}} {{- if $showAnchor -}}
{{ .Text | safeHTML }}
{{- else -}}
{{ .Text | safeHTML }}
{{- end -}} ================================================ FILE: layouts/_default/_markup/render-image.html ================================================ {{ .Text }} {{- /* Drop trailing newlines */ -}} ================================================ FILE: layouts/_default/_markup/render-link.html ================================================ {{- $raw := or (hasPrefix .Text " {{- .Text | safeHTML -}} {{- /* Drop trailing newlines */ -}} ================================================ FILE: layouts/_default/baseof.html ================================================ {{ partial "head/meta" . }} {{- if eq .Kind "home" -}} {{ .Site.Title }} {{- else -}} {{ printf "%s | %s" (partial "utils/title" .) .Site.Title }} {{- end -}} {{ partial "head/favicons" . }} {{ partial "head/rel-me" . }} {{ partial "head/microformats" . }} {{ partial "head/others" . }} {{ partial "head/custom" . }} {{ partial "svg-icon-symbols" . }}
{{ $navEnabled := default true .Page.Params.geekdocNav }} {{ partial "site-header" (dict "Root" . "MenuEnabled" $navEnabled) }}
{{ if $navEnabled }} {{ end }}
{{ template "main" . }} {{ $showPrevNext := (default true .Site.Params.geekdocNextPrev) }} {{ if $showPrevNext }} {{ end }}
{{ partial "site-footer" . }}
{{ partial "foot" . }} ================================================ FILE: layouts/_default/list.html ================================================ {{ define "main" }} {{ partial "page-header" . }}

{{ partial "utils/title" . }}

{{ partial "utils/content" . }}
{{ end }} ================================================ FILE: layouts/_default/single.html ================================================ {{ define "main" }} {{ partial "page-header" . }}

{{ partial "utils/title" . }}

{{ partial "page-metadata" . }} {{ partial "utils/content" . }}
{{ end }} ================================================ FILE: layouts/_default/taxonomy.html ================================================ {{ define "main" }}
{{ range .Paginator.Pages }} {{ end }}
{{ partial "pagination.html" . }} {{ end }} {{ define "post-tag" }} {{ end }} ================================================ FILE: layouts/_default/terms.html ================================================ {{ define "main" }}
{{ range .Paginator.Pages.ByTitle }} {{ end }}
{{ partial "pagination.html" . }} {{ end }} ================================================ FILE: layouts/partials/foot.html ================================================ ================================================ FILE: layouts/partials/head/custom.html ================================================ ================================================ FILE: layouts/partials/head/favicons.html ================================================ ================================================ FILE: layouts/partials/head/meta.html ================================================ {{ hugo.Generator }} {{ $keywords := default .Site.Params.Keywords .Keywords }} {{- with partial "utils/description" . }} {{- end }} {{- with $keywords }} {{- end }} ================================================ FILE: layouts/partials/head/microformats.html ================================================ {{ partial "microformats/opengraph.html" . }} {{ partial "microformats/twitter_cards.html" . }} {{ partial "microformats/schema" . }} ================================================ FILE: layouts/partials/head/others.html ================================================ {{- if default true .Site.Params.geekdocDarkModeToggle }} {{- end }} {{- with .OutputFormats.Get "html" }} {{ printf `` .Permalink .Rel .MediaType.Type | safeHTML }} {{- end }} {{- if (default false $.Site.Params.geekdocOverwriteHTMLBase) }} {{- end }} {{ printf "" "Made with Geekdoc theme https://github.com/thegeeklab/hugo-geekdoc" | safeHTML }} ================================================ FILE: layouts/partials/head/rel-me.html ================================================ ================================================ FILE: layouts/partials/language.html ================================================ {{ if hugo.IsMultilingual }}
  • {{ range .Site.Languages }} {{ if eq . $.Site.Language }} {{ .Lang | upper }} {{ end }} {{ end }}
{{ end }} ================================================ FILE: layouts/partials/menu-bundle-np.html ================================================ {{ $current := . }} {{ $site := .Site }} {{ $current.Scratch.Set "prev" false }} {{ $current.Scratch.Set "getNext" false }} {{ $current.Scratch.Set "nextPage" false }} {{ $current.Scratch.Set "prevPage" false }} {{ template "menu-bundle-np" dict "sect" hugo.Data.menu.main.main "current" $current "site" $site }} {{ define "menu-bundle-np" }} {{ $current := .current }} {{ $site := .site }} {{ range sort (default (seq 0) .sect) "weight" }} {{ $current.Scratch.Set "current" $current }} {{ $current.Scratch.Set "site" $site }} {{ $ref := default false .ref }} {{ if $ref }} {{ $site := $current.Scratch.Get "site" }} {{ $this := $site.GetPage .ref }} {{ $current := $current.Scratch.Get "current" }} {{ if reflect.IsMap .name }} {{ $current.Scratch.Set "refName" (index .name $site.Language.Lang) }} {{ else }} {{ $current.Scratch.Set "refName" .name }} {{ end }} {{ $name := $current.Scratch.Get "refName" }} {{ if $current.Scratch.Get "getNext" }} {{ $current.Scratch.Set "nextPage" (dict "name" $name "this" $this) }} {{ $current.Scratch.Set "getNext" false }} {{ end }} {{ if eq $current $this }} {{ $current.Scratch.Set "prevPage" ($current.Scratch.Get "prev") }} {{ $current.Scratch.Set "getNext" true }} {{ end }} {{ $current.Scratch.Set "prev" (dict "name" $name "this" $this) }} {{ end }} {{ $sub := default false .sub }} {{ if $sub }} {{ template "menu-bundle-np" dict "sect" $sub "current" ($current.Scratch.Get "current") "site" ($current.Scratch.Get "site") }} {{ end }} {{ end }} {{ end }} {{ with ($current.Scratch.Get "prevPage") }} gdoc_arrow_left_alt {{ .name }} {{ end }} {{ with ($current.Scratch.Get "nextPage") }} {{ .name }} gdoc_arrow_right_alt {{ end }} ================================================ FILE: layouts/partials/menu-bundle.html ================================================ {{ $current := .current }} {{ template "menu-file" dict "sect" .source "current" $current "site" $current.Site }} {{ define "menu-file" }} {{ $current := .current }} {{ $site := .site }}
    {{ range sort (default (seq 0) .sect) "weight" }} {{ $name := .name }} {{ if reflect.IsMap .name }} {{ $name = (index .name $site.Language.Lang) }} {{ end }}
  • {{ $ref := default false .ref }} {{ if $ref }} {{ $this := $site.GetPage .ref }} {{ $icon := default false .icon }} {{ $numberOfPages := (add (len $this.Pages) (len $this.Sections)) }} {{ $isCurrent := eq $current $this }} {{ $isAncestor := $this.IsAncestor $current }} {{ $id := substr (sha1 $this.Permalink) 0 8 }} {{ $doCollapse := and (isset . "sub") (or $this.Params.geekdocCollapseSection (default false .Site.Params.geekdocCollapseAllSections)) }} {{ $anchor := default "" .anchor }} {{ if $anchor }} {{ $anchor = printf "#%s" $anchor }} {{ end }} {{ if or .external ($this.RelPermalink) }} {{ end }} {{ else }} {{ $name }} {{ end }} {{ with .sub }} {{ template "menu-file" dict "sect" . "current" $current "site" $site }} {{ end }}
  • {{ end }}
{{ end }} ================================================ FILE: layouts/partials/menu-extra.html ================================================ {{ $current := .current }} {{ template "menu-extra" dict "sect" .source "current" $current "site" $current.Site "target" .target }} {{ define "menu-extra" }} {{ $current := .current }} {{ $site := .site }} {{ $target := .target }} {{ $sect := .sect }} {{ range sort (default (seq 0) $sect) "weight" }} {{ if isset . "ref" }} {{ $this := $site.GetPage .ref }} {{ $isCurrent := eq $current $this }} {{ $icon := default false .icon }} {{ $name := .name }} {{ if reflect.IsMap .name }} {{ $name = (index .name $site.Language.Lang) }} {{ end }} {{ if not .icon }} {{ errorf "Missing 'icon' attribute in data file for '%s' menu item '%s'" $target $name }} {{ end }} {{ if eq $target "header" }} {{ $name }} {{ end }} {{ end }} {{ end }} {{ end }} ================================================ FILE: layouts/partials/menu-filetree-np.html ================================================ {{ $current := . }} {{ $site := .Site }} {{ $current.Scratch.Set "prev" false }} {{ $current.Scratch.Set "getNext" false }} {{ $current.Scratch.Set "nextPage" false }} {{ $current.Scratch.Set "prevPage" false }} {{ template "menu-filetree-np" dict "sect" .Site.Home.Sections "current" $current "site" $site }} {{ define "menu-filetree-np" }} {{ $current := .current }} {{ $site := .site }} {{ $sortBy := (default "title" .current.Site.Params.geekdocFileTreeSortBy | lower) }} {{ range .sect.GroupBy "Weight" }} {{ $rangeBy := .ByTitle }} {{ if eq $sortBy "title" }} {{ $rangeBy = .ByTitle }} {{ else if eq $sortBy "linktitle" }} {{ $rangeBy = .ByLinkTitle }} {{ else if eq $sortBy "date" }} {{ $rangeBy = .ByDate }} {{ else if eq $sortBy "publishdate" }} {{ $rangeBy = .ByPublishDate }} {{ else if eq $sortBy "expirydate" }} {{ $rangeBy = .ByExpiryDate }} {{ else if eq $sortBy "lastmod" }} {{ $rangeBy = .ByLastmod }} {{ else if eq $sortBy "title_reverse" }} {{ $rangeBy = .ByTitle.Reverse }} {{ else if eq $sortBy "linktitle_reverse" }} {{ $rangeBy = .ByLinkTitle.Reverse }} {{ else if eq $sortBy "date_reverse" }} {{ $rangeBy = .ByDate.Reverse }} {{ else if eq $sortBy "publishdate_reverse" }} {{ $rangeBy = .ByPublishDate.Reverse }} {{ else if eq $sortBy "expirydate_reverse" }} {{ $rangeBy = .ByExpiryDate.Reverse }} {{ else if eq $sortBy "lastmod_reverse" }} {{ $rangeBy = .ByLastmod.Reverse }} {{ end }} {{ range $rangeBy }} {{ $current.Scratch.Set "current" $current }} {{ $current.Scratch.Set "site" $site }} {{ if not .Params.geekdocHidden }} {{ $numberOfPages := (add (len .Pages) (len .Sections)) }} {{ $site := $current.Scratch.Get "site" }} {{ $this := . }} {{ $current := $current.Scratch.Get "current" }} {{ $current.Scratch.Set "refName" (partial "utils/title" .) }} {{ $name := $current.Scratch.Get "refName" }} {{ if $current.Scratch.Get "getNext" }} {{ if or $this.Content $this.Params.geekdocFlatSection }} {{ $current.Scratch.Set "nextPage" (dict "name" $name "this" $this) }} {{ $current.Scratch.Set "getNext" false }} {{ end }} {{ end }} {{ if eq $current.RelPermalink $this.RelPermalink }} {{ $current.Scratch.Set "prevPage" ($current.Scratch.Get "prev") }} {{ $current.Scratch.Set "getNext" true }} {{ end }} {{ if or $this.Content $this.Params.geekdocFlatSection }} {{ $current.Scratch.Set "prev" (dict "name" $name "this" $this) }} {{ end }} {{ $sub := and (ne $numberOfPages 0) (not .Params.geekdocFlatSection) }} {{ if $sub }} {{ template "menu-filetree-np" dict "sect" .Pages "current" $current }} {{ end }} {{ end }} {{ end }} {{ end }} {{ end }} {{ with ($current.Scratch.Get "prevPage") }} gdoc_arrow_left_alt {{ .name }} {{ end }} {{ with ($current.Scratch.Get "nextPage") }} {{ .name }} gdoc_arrow_right_alt {{ end }} ================================================ FILE: layouts/partials/menu-filetree.html ================================================ {{ $current := . }} {{ template "tree-nav" dict "sect" .Site.Home.Sections "current" $current }} {{ define "tree-nav" }} {{ $current := .current }}
    {{ $sortBy := (default "title" .current.Site.Params.geekdocFileTreeSortBy | lower) }} {{ range .sect.GroupBy "Weight" }} {{ $rangeBy := .ByTitle }} {{ if eq $sortBy "title" }} {{ $rangeBy = .ByTitle }} {{ else if eq $sortBy "linktitle" }} {{ $rangeBy = .ByLinkTitle }} {{ else if eq $sortBy "date" }} {{ $rangeBy = .ByDate }} {{ else if eq $sortBy "publishdate" }} {{ $rangeBy = .ByPublishDate }} {{ else if eq $sortBy "expirydate" }} {{ $rangeBy = .ByExpiryDate }} {{ else if eq $sortBy "lastmod" }} {{ $rangeBy = .ByLastmod }} {{ else if eq $sortBy "title_reverse" }} {{ $rangeBy = .ByTitle.Reverse }} {{ else if eq $sortBy "linktitle_reverse" }} {{ $rangeBy = .ByLinkTitle.Reverse }} {{ else if eq $sortBy "date_reverse" }} {{ $rangeBy = .ByDate.Reverse }} {{ else if eq $sortBy "publishdate_reverse" }} {{ $rangeBy = .ByPublishDate.Reverse }} {{ else if eq $sortBy "expirydate_reverse" }} {{ $rangeBy = .ByExpiryDate.Reverse }} {{ else if eq $sortBy "lastmod_reverse" }} {{ $rangeBy = .ByLastmod.Reverse }} {{ end }} {{ range $rangeBy }} {{ if not .Params.geekdocHidden }} {{ $numberOfPages := (add (len .Pages) (len .Sections)) }} {{ $isParent := and (ne $numberOfPages 0) (not .Params.geekdocFlatSection) }} {{ $isCurrent := eq $current . }} {{ $isAncestor := .IsAncestor $current }} {{ $id := substr (sha1 .Permalink) 0 8 }} {{ $doCollapse := and $isParent (or .Params.geekdocCollapseSection (default false .Site.Params.geekdocCollapseAllSections)) }}
  • {{ if $isParent }} {{ template "tree-nav" dict "sect" .Pages "current" $current }} {{ end }}
  • {{ end }} {{ end }} {{ end }}
{{ end }} ================================================ FILE: layouts/partials/menu.html ================================================ ================================================ FILE: layouts/partials/microformats/opengraph.html ================================================ {{ $isPage := or (and (ne .Type "posts") (in "section page" .Kind )) (and (eq .Type "posts") (eq .Kind "page")) }} {{- if ne .Kind "home" }} {{- end }} {{- with .Site.Title }} {{- end }} {{- with partial "utils/featured" . }} {{- end }} {{- with partial "utils/description" . }} {{- end }} {{- with .Params.audio }} {{- end }} {{- with .Params.locale }} {{- end }} {{- with .Params.videos }} {{- range . }} {{- end }} {{- end }} {{- /* If it is part of a series, link to related articles */}} {{- if .Site.Taxonomies.series }} {{- $permalink := .Permalink -}} {{- $siteSeries := .Site.Taxonomies.series -}} {{- with .Params.series }} {{- range $name := . }} {{- $series := index $siteSeries ($name | urlize) }} {{- range $page := first 6 $series.Pages }} {{- if ne $page.Permalink $permalink }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{ if $isPage -}} {{- $iso8601 := "2006-01-02T15:04:05-07:00" -}} {{- with .PublishDate }} {{- end }} {{- with .Lastmod }} {{- end }} {{- end }} {{- /* Facebook Page Admin ID for Domain Insights */}} {{- with .Site.Params.facebook_admin }} {{- end }} ================================================ FILE: layouts/partials/microformats/schema.html ================================================ {{ $isPage := or (and (ne .Type "posts") (in "section page" .Kind )) (and (eq .Type "posts") (eq .Kind "page")) }} {{- if eq .Kind "home" }} {{- else if $isPage }} {{- end }} ================================================ FILE: layouts/partials/microformats/twitter_cards.html ================================================ {{- with partial "utils/featured" . }} {{- else }} {{- end }} {{- with partial "utils/featured" . }} {{- end }} {{- with partial "utils/description" . }} {{- end }} {{- with .Site.Params.twitter -}} {{- end }} ================================================ FILE: layouts/partials/page-header.html ================================================ {{ $geekdocRepo := default (default false .Site.Params.geekdocRepo) .Page.Params.geekdocRepo }} {{ $geekdocEditPath := default (default false .Site.Params.geekdocEditPath) .Page.Params.geekdocEditPath }} {{ if .File }} {{ $.Scratch.Set "geekdocFilePath" (default (strings.TrimPrefix hugo.WorkingDir .File.Filename) .Page.Params.geekdocFilePath) }} {{ else }} {{ $.Scratch.Set "geekdocFilePath" false }} {{ end }} {{ define "breadcrumb" }} {{ $parent := .page.Parent }} {{ if $parent }} {{ $name := (partial "utils/title" $parent) }} {{ $position := (sub .position 1) }} {{ $value := (printf "
  • %s
  • /
  • %s" $parent.RelPermalink $parent.RelPermalink $name $position .value) }} {{ template "breadcrumb" dict "page" $parent "value" $value "position" $position }} {{ else }} {{ .value | safeHTML }} {{ end }} {{ end }} {{ $showBreadcrumb := (and (default true .Page.Params.geekdocBreadcrumb) (default true .Site.Params.geekdocBreadcrumb)) }} {{ $showEdit := (and ($.Scratch.Get "geekdocFilePath") $geekdocRepo $geekdocEditPath) }}
    {{ if $showBreadcrumb }}
    {{ end }} {{ if $showEdit }} {{ end }}
    ================================================ FILE: layouts/partials/page-metadata.html ================================================ {{- $showPageLastmod := (or (default false .Page.Params.geekdocPageLastmod) (default false .Site.Params.geekdocPageLastmod)) -}} {{- if $showPageLastmod -}} {{- end -}} ================================================ FILE: layouts/partials/pagination.html ================================================ {{ $page := $.Paginator }} ================================================ FILE: layouts/partials/posts/metadata.html ================================================ {{ $tc := 0 }} {{ with .Params.tags }} {{ range sort . }} {{ $name := . }} {{ with $.Site.GetPage (printf "/tags/%s" $name | urlize) }} {{ if eq $tc 0 }} {{ template "post-tag" dict "name" $name "page" . }} {{ else }} {{ template "post-tag" dict "name" $name "page" . }} {{ end }} {{ end }} {{ $tc = (add $tc 1) }} {{ end }} {{ end }} {{ define "post-tag" }} {{ end }} ================================================ FILE: layouts/partials/search.html ================================================ {{ if default true .Site.Params.geekdocSearch }} {{- $searchConfigFile := printf "search/%s.config.json" .Language.Lang -}} {{- $searchConfig := resources.Get "search/config.json" | resources.ExecuteAsTemplate $searchConfigFile . | resources.Minify -}} {{- $searchConfig.Publish -}} {{ end }} ================================================ FILE: layouts/partials/site-footer.html ================================================ ================================================ FILE: layouts/partials/site-header.html ================================================
    {{ if .MenuEnabled }} {{ end }}
    {{ if .Roothugo.Data.menu.extra.header }} {{ partial "menu-extra" (dict "current" .Root "source" .Roothugo.Data.menu.extra.header "target" "header") }} {{ end }} {{ i18n "button_toggle_dark" }} {{ i18n "button_toggle_dark" }} {{ i18n "button_toggle_dark" }} {{ i18n "button_homepage" }} {{ partial "language" .Root }}
    ================================================ FILE: layouts/partials/svg-icon-symbols.html ================================================ {{ range resources.Match "sprites/*.svg" }} {{ printf "" . | safeHTML }} {{ .Content | safeHTML }} {{ end }} ================================================ FILE: layouts/partials/utils/content.html ================================================ {{ $content := .Content }} {{ $content = $content | replaceRE `` `` | safeHTML }} {{ $content = $content | replaceRE `((?:.|\n)+?
    )` `
    ${1}
    ` | safeHTML }} {{ return $content }} ================================================ FILE: layouts/partials/utils/description.html ================================================ {{ $isPage := or (and (ne .Type "posts") (in "section page" .Kind )) (and (eq .Type "posts") (eq .Kind "page")) }} {{ $description := "" }} {{ if .Description }} {{ $description = .Description }} {{ else }} {{ if $isPage }} {{ $description = .Summary }} {{ else if .Site.Params.description }} {{ $description = .Site.Params.description }} {{ end }} {{ end }} {{ return $description }} ================================================ FILE: layouts/partials/utils/featured.html ================================================ {{ $img := "" }} {{ with $source := ($.Resources.ByType "image").GetMatch "{*feature*,*cover*,*thumbnail*}" }} {{ $featured := .Fill (printf "1200x630 %s" (default "Smart" .Params.anchor)) }} {{ $img = $featured.Permalink }} {{ else }} {{ with default $.Site.Params.images $.Params.images }} {{ $img = index . 0 | absURL }} {{ end }} {{ end }} {{ return $img }} ================================================ FILE: layouts/partials/utils/title.html ================================================ {{ $title := "" }} {{ if .Title }} {{ $title = .Title }} {{ else if and .IsSection .File }} {{ $title = path.Base .File.Dir | humanize | title }} {{ else if and .IsPage .File }} {{ $title = .File.BaseFileName | humanize | title }} {{ end }} {{ return $title }} ================================================ FILE: layouts/posts/list.html ================================================ {{ define "main" }}
    {{ range .Paginator.Pages }} {{ end }}
    {{ partial "pagination.html" . }} {{ end }} {{ define "post-tag" }} {{ end }} ================================================ FILE: layouts/posts/single.html ================================================ {{ define "main" }}

    {{ partial "utils/title" . }}

    {{ partial "utils/content" . }}
    {{ end }} ================================================ FILE: layouts/robots.txt ================================================ User-agent: * Disallow: /tags/* Sitemap: {{ "sitemap.xml" | absURL }} ================================================ FILE: layouts/shortcodes/audio.html ================================================ {{- $source := ($.Page.Resources.ByType "audio").GetMatch (printf "%s" (.Get "name")) }} {{- $customAlt := .Get "alt" }} {{- with $source }} {{- $caption := default .Title $customAlt }}
    {{- with $caption }}
    {{ . }} {{- with $source.Params.credits }} {{ printf " (%s)" . | $.Page.RenderString }} {{- end }}
    {{- end }}
    {{- end }} ================================================ FILE: layouts/shortcodes/avatar.html ================================================ {{- $source := ($.Page.Resources.ByType "image").GetMatch (printf "%s" (.Get "name")) }} {{- $customAlt := .Get "alt" }} {{- $customSize := .Get "size" | lower }} {{- $customAnchor := default "smart" (.Get "anchor") | title }} {{- $data := newScratch }} {{- with $source }} {{- $caption := default .Title $customAlt }} {{- $isSVG := (eq .MediaType.SubType "svg") }} {{- $origin := . -}} {{- if $isSVG }} {{- $data.SetInMap "size" "tiny" "160" }} {{- $data.SetInMap "size" "small" "300" }} {{- $data.SetInMap "size" "medium" "600" }} {{- $data.SetInMap "size" "large" "900" }} {{- else }} {{- $data.SetInMap "size" "tiny" (printf "160x160 %s" $customAnchor) }} {{- $data.SetInMap "size" "small" (printf "300x300 %s" $customAnchor) }} {{- $data.SetInMap "size" "medium" (printf "600x600 %s" $customAnchor) }} {{- $data.SetInMap "size" "large" (printf "900x900 %s" $customAnchor) }} {{- end -}} {{- end }} ================================================ FILE: layouts/shortcodes/button.html ================================================ {{- $ref := "" }} {{- $class := "" }} {{- $size := default "regular" (.Get "size" | lower) }} {{- if not (in (slice "regular" "large") $size) }} {{- $size = "regular" }} {{- end }} {{- with .Get "href" }} {{- $ref = . }} {{- end }} {{- with .Get "relref" }} {{- $ref = relref $ . }} {{- end }} {{- with .Get "class" }} {{- $class = . }} {{- end }} {{ $.Inner }} ================================================ FILE: layouts/shortcodes/columns.html ================================================ {{- $size := default "regular" (.Get "size" | lower) }} {{- if not (in (slice "regular" "large" "small") $size) }} {{- $size = "regular" }} {{- end }}
    {{- range split .Inner "<--->" }}
    {{ . | $.Page.RenderString -}}
    {{- end }}
    ================================================ FILE: layouts/shortcodes/expand.html ================================================ {{ $id := substr (sha1 .Inner) 0 8 }}
    {{ .Inner | $.Page.RenderString }}
    ================================================ FILE: layouts/shortcodes/gist.html ================================================ ================================================ FILE: layouts/shortcodes/hint.html ================================================ {{- $type := default "note" (.Get "type") }} {{- $icon := .Get "icon" }} {{- $title := default ($type | title) (.Get "title") }}
    {{- with $icon -}} {{ $title }} {{- else -}} {{ $title }} {{- end -}}
    {{ .Inner | $.Page.RenderString }}
    ================================================ FILE: layouts/shortcodes/icon.html ================================================ {{ $id := .Get 0 }} {{- with $id -}} {{- end -}} ================================================ FILE: layouts/shortcodes/img.html ================================================ {{- $source := ($.Page.Resources.ByType "image").GetMatch (printf "%s" (.Get "name")) }} {{- $customAlt := .Get "alt" }} {{- $customSize := .Get "size" | lower }} {{- $lazyLoad := default (default true $.Site.Params.geekdocImageLazyLoading) (.Get "lazy") }} {{- $data := newScratch }} {{- with $source }} {{- $caption := default .Title $customAlt }} {{- $isSVG := (eq .MediaType.SubType "svg") }} {{- $origin := . }} {{- if $isSVG }} {{- $data.SetInMap "size" "tiny" "320" }} {{- $data.SetInMap "size" "small" "600" }} {{- $data.SetInMap "size" "medium" "1200" }} {{- $data.SetInMap "size" "large" "1800" }} {{- else }} {{- $data.SetInMap "size" "tiny" "320x"}} {{- $data.SetInMap "size" "small" "600x" }} {{- $data.SetInMap "size" "medium" "1200x" }} {{- $data.SetInMap "size" "large" "1800x" }} {{- end -}}
    {{- $size := $data.Get "size" }} {{- if not $isSVG }} {{- if ne $customSize "origin" }} {{- end }} {{- end }} {{ $caption }} {{- with $caption }}
    {{ . }} {{- with $source.Params.credits }} {{ printf " (%s)" . | $.Page.RenderString }} {{- end }}
    {{- end }}
    {{- end }} ================================================ FILE: layouts/shortcodes/include.html ================================================ {{ $file := .Get "file" }} {{ $page := .Site.GetPage $file }} {{ $type := .Get "type" }} {{ $language := .Get "language" }} {{ $options :=.Get "options" }}
    {{- if (.Get "language") -}} {{- highlight ($file | readFile) $language (default "linenos=table" $options) -}} {{- else if eq $type "html" -}} {{- $file | readFile | safeHTML -}} {{- else if eq $type "page" -}} {{- with $page }}{{ .Content }}{{ end -}} {{- else -}} {{- $file | readFile | $.Page.RenderString -}} {{- end -}}
    ================================================ FILE: layouts/shortcodes/katex.html ================================================ {{ if not (.Page.Scratch.Get "katex") }} {{ .Page.Scratch.Set "katex" true }} {{ end }} {{ cond (in .Params "display") "\\[" "\\(" -}} {{- trim .Inner "\n" -}} {{- cond (in .Params "display") "\\]" "\\)" -}} {{- /* Drop trailing newlines */ -}} ================================================ FILE: layouts/shortcodes/mermaid.html ================================================ {{ if not (.Page.Scratch.Get "mermaid") }} {{ .Page.Scratch.Set "mermaid" true }} {{ end }}
      {{- .Inner -}}
    
    ================================================ FILE: layouts/shortcodes/progress.html ================================================ {{- $value := default 0 (.Get "value") -}} {{- $label := default (printf "%v %%" $value) (.Get "label") -}} {{- $type := default "main" (.Get "type") -}} {{- $title := .Get "title" -}} {{- $icon := .Get "icon" -}}
    {{ with $icon -}} {{- end }} {{ with $title }}{{ . }}{{ end }}
    {{ $label }}
    ================================================ FILE: layouts/shortcodes/propertylist.html ================================================ {{- $name := .Get "name" -}} {{- $sort := .Get "sort" -}} {{- $order := default "asc" (.Get "order") -}} {{- $showAnchor := (and (default true .Page.Params.geekdocAnchor) (default true .Page.Site.Params.geekdocAnchor)) -}} {{- if hugo.Data.properties }}
    {{- with (index hugo.Data.properties (split $name ".")) }} {{- $properties := .properties }} {{- with $sort }} {{- $properties = (sort $properties . $order) }} {{- end }} {{- range $properties }} {{- $uniqueAnchor := anchorize (printf "%s-%s" $name .name) | safeHTML }}
    {{ .name }} {{- if .required }} {{ i18n "propertylist_required" | lower }} {{- else }} {{ i18n "propertylist_optional" | lower }} {{- end }} {{- with .type }} {{ . }} {{- end }} {{- with .tags }} {{- $tags := . }} {{- if reflect.IsMap $tags }} {{- $tags = (index $tags $.Site.Language.Lang) }} {{- end }} {{- range $tags }} {{ . }} {{- end }} {{- end }} {{- if $showAnchor }} {{- end }}
    {{- with .description }} {{- $desc := . }} {{- if reflect.IsMap $desc }} {{- $desc = (index $desc $.Site.Language.Lang) }} {{- end }} {{ $desc | $.Page.RenderString }} {{- end }}
    {{- with default "none" (.defaultValue | string) }} {{ i18n "propertylist_default" | title }}: {{ . }} {{- end }}
    {{- end }} {{- end }}
    {{- end }} ================================================ FILE: layouts/shortcodes/tab.html ================================================ {{- if .Parent }} {{- $name := .Get 0 }} {{- $group := printf "tabs-%s" (.Parent.Get 0) }} {{- if not (.Parent.Scratch.Get $group) }} {{- .Parent.Scratch.Set $group slice }} {{- end }} {{- .Parent.Scratch.Add $group (dict "Name" $name "Content" .Inner) }} {{- else }} {{ errorf "%q: 'tab' shortcode must be inside 'tabs' shortcode" .Page.Path }} {{- end }} ================================================ FILE: layouts/shortcodes/tabs.html ================================================ {{- if .Inner }}{{ end }} {{- $id := .Get 0 }} {{- $group := printf "tabs-%s" $id }}
    {{- range $index, $tab := .Scratch.Get $group }}
    {{ .Content | $.Page.RenderString -}}
    {{- end }}
    ================================================ FILE: layouts/shortcodes/toc-tree.html ================================================ {{- $current := . }} {{- $tocLevels := default (default 6 .Site.Params.geekdocToC) .Page.Params.geekdocToC }} {{- $sortBy := (default (default "title" .Site.Params.geekdocFileTreeSortBy) (.Get "sortBy") | lower) }} {{- if $tocLevels }}
    {{ template "toc-tree" dict "sect" .Page.Pages "current" $current "sortBy" $sortBy }}
    {{- end }} {{- define "toc-tree" }}
      {{ range .sect.GroupBy "Weight" }} {{ $rangeBy := .ByTitle }} {{ if eq $.sortBy "title" }} {{ $rangeBy = .ByTitle }} {{ else if eq $.sortBy "linktitle" }} {{ $rangeBy = .ByLinkTitle }} {{ else if eq $.sortBy "date" }} {{ $rangeBy = .ByDate }} {{ else if eq $.sortBy "publishdate" }} {{ $rangeBy = .ByPublishDate }} {{ else if eq $.sortBy "expirydate" }} {{ $rangeBy = .ByExpiryDate }} {{ else if eq $.sortBy "lastmod" }} {{ $rangeBy = .ByLastmod }} {{ else if eq $.sortBy "title_reverse" }} {{ $rangeBy = .ByTitle.Reverse }} {{ else if eq $.sortBy "linktitle_reverse" }} {{ $rangeBy = .ByLinkTitle.Reverse }} {{ else if eq $.sortBy "date_reverse" }} {{ $rangeBy = .ByDate.Reverse }} {{ else if eq $.sortBy "publishdate_reverse" }} {{ $rangeBy = .ByPublishDate.Reverse }} {{ else if eq $.sortBy "expirydate_reverse" }} {{ $rangeBy = .ByExpiryDate.Reverse }} {{ else if eq $.sortBy "lastmod_reverse" }} {{ $rangeBy = .ByLastmod.Reverse }} {{ end }} {{ range $rangeBy }} {{- if or (not .Params.geekdocHidden) (not (default true .Params.geekdocHiddenTocTree)) }}
    • {{- if or .Content .Params.geekdocFlatSection }} {{- partial "utils/title" . }}{{ with .Params.geekdocDescription }}:{{ end }} {{- with .Params.geekdocDescription }}{{ . }}{{ end }} {{- else -}} {{- partial "utils/title" . }}{{ with .Params.geekdocDescription }} : {{ . }} {{ end }} {{- end -}} {{- $numberOfPages := (add (len .Pages) (len .Sections)) }} {{- if and (ne $numberOfPages 0) (not .Params.geekdocFlatSection) }} {{- template "toc-tree" dict "sect" .Pages }} {{- end }}
    • {{- end }} {{- end }} {{- end }}
    {{- end }} ================================================ FILE: layouts/shortcodes/toc.html ================================================ {{- $format := default "html" (.Get "format") }} {{- $tocLevels := default (default 6 .Site.Params.geekdocToC) .Page.Params.geekdocToC }} {{- if and $tocLevels .Page.TableOfContents -}} {{- if not (eq ($format | lower) "raw") -}}
    {{ .Page.TableOfContents }}
    {{- else -}} {{ .Page.TableOfContents }} {{- end -}} {{- end -}} ================================================ FILE: package.json ================================================ { "name": "geekdoc", "version": "1.0.0", "description": "Hugo theme made for documentation", "main": "index.js", "type": "module", "scripts": { "build": "run-s prep:clean prep:make svg build:webpack", "build:webpack": "webpack --mode=production", "build:webpack-devel": "webpack --mode=development", "pack": "tar -zcvf dist/hugo-geekdoc.tar.gz -X .tarignore .", "start": "run-s prep:clean prep:make svg build:webpack-devel ; run-p start:webpack start:hugo", "start:webpack": "webpack --mode=development --watch", "start:build": "webpack --mode=development", "start:hugo": "hugo server -D -F -s exampleSite/", "svg": "run-s svg:*", "svg:sprite": "svg-sprite -C svgsprite.config.json 'src/icons/*.svg'", "svg:font": "svgtofont --sources build/icons/ --output build/fonts/", "prep:clean": "shx rm -rf build/ static/", "prep:clean-all": "shx rm -rf VERSION .lighthouseci/ lhci_reports/ build/ dist/ static/ data/ assets/sprites/ exampleSite/data/sprites/ exampleSite/public/ exampleSite/resources/ exampleSite/.hugo_build.lock", "prep:make": "shx mkdir -p build/icons/ build/fonts/ dist/", "svg-sprite-list": "run-s prep:make svg ; shx mkdir -p exampleSite/data/sprites/ ; shx cp build/fonts/GeekdocIcons.json exampleSite/data/sprites/geekdoc.json", "lint": "run-p lint:js lint:html", "lint:js": "eslint src/js/ --color", "lint:html": "html-validate exampleSite/public" }, "repository": { "type": "git", "url": "https://github.com/thegeeklab/hugo-geekdoc" }, "author": "Robert Kaussow", "license": "MIT", "engines": { "node": ">=20 <=24" }, "dependencies": { "@cfworker/json-schema": "4.1.1", "clipboard": "2.0.11", "flexsearch": "0.8.212", "katex": "0.16.45", "lodash": "4.18.1", "mermaid": "11.14.0", "store2": "2.14.4", "uuid": "13.0.0" }, "devDependencies": { "@eslint/js": "10.0.1", "autoprefixer": "10.4.27", "copy-webpack-plugin": "14.0.0", "css-loader": "7.1.4", "eslint": "10.2.0", "eslint-config-prettier": "10.1.8", "eslint-plugin-prettier": "5.5.5", "favicons": "7.2.0", "favicons-webpack-plugin": "6.0.1", "globals": "17.4.0", "html-validate": "10.11.3", "npm-run-all2": "8.0.4", "postcss-loader": "8.2.1", "prettier": "3.8.1", "sass": "1.99.0", "sass-loader": "16.0.7", "shx": "0.4.0", "svg-sprite": "2.0.4", "svgtofont": "6.5.1", "webpack": "5.105.4", "webpack-cli": "7.0.2", "webpack-manifest-plugin": "6.0.1", "webpack-remove-empty-scripts": "1.1.1" }, "overrides": { "colors": "1.4.0" }, "browserslist": [ "last 2 version", "> 5%", "not dead", "Firefox ESR" ], "svgtofont": { "fontName": "GeekdocIcons", "css": false, "html": false, "emptyDist": true, "useNameAsUnicode": true, "svgicons2svgfont": { "fontHeight": 1001, "normalize": true, "centerHorizontally": true, "centerVertically": true } } } ================================================ FILE: renovate.json ================================================ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["github>thegeeklab/renovate-presets"] } ================================================ FILE: src/js/accessibility.js ================================================ document.addEventListener("DOMContentLoaded", () => { const gdocNav = document.querySelector(".gdoc-nav") const gdocPage = document.querySelector(".gdoc-page") const menuControl = document.getElementById("menu-control") // Helper function for menu navigation accessibility const updateMenuAccessibility = () => { if (!gdocNav || !gdocPage || !menuControl) return const isMenuOpen = menuControl.checked const isDesktop = window.matchMedia("(min-width: 41rem)").matches // Set nav accessibility attributes gdocNav.toggleAttribute("inert", !isDesktop && !isMenuOpen) gdocNav.setAttribute("aria-hidden", (!isDesktop && !isMenuOpen).toString()) // Set page accessibility attributes gdocPage.toggleAttribute("inert", !isDesktop && isMenuOpen) gdocPage.setAttribute("aria-hidden", (!isDesktop && isMenuOpen).toString()) } // Process all button role elements document.querySelectorAll('[role="button"]').forEach((buttonElement) => { const controlId = buttonElement.parentElement?.getAttribute("for") if (!controlId) return const controlElement = document.getElementById(controlId) if (!controlElement || controlElement.type !== "checkbox") return // Set initial accessibility state buttonElement.setAttribute("aria-pressed", controlElement.checked) // Handle accessibility updates const updateButton = () => { buttonElement.setAttribute("aria-pressed", controlElement.checked) if (controlId === "menu-control") updateMenuAccessibility() } // Event listeners buttonElement.addEventListener("click", updateButton) buttonElement.addEventListener("keydown", (event) => { if (event.key === "Enter") { controlElement.checked = !controlElement.checked updateButton() event.preventDefault() } }) }) // Initial call and resize handler updateMenuAccessibility() window.addEventListener("resize", updateMenuAccessibility) }) ================================================ FILE: src/js/colorTheme.js ================================================ import Storage from "store2" import { TOGGLE_COLOR_THEMES, THEME, COLOR_THEME_AUTO } from "./config.js" const applyTheme = (init = true) => { if (Storage.isFake()) return const lstore = Storage.namespace(THEME) const html = document.documentElement const currentColorTheme = TOGGLE_COLOR_THEMES.includes(lstore.get("color-theme")) ? lstore.get("color-theme") : COLOR_THEME_AUTO html.setAttribute("class", `color-toggle-${currentColorTheme}`) if (currentColorTheme === COLOR_THEME_AUTO) { html.removeAttribute("color-theme") } else { html.setAttribute("color-theme", currentColorTheme) } if (!init) { // Reload required to re-initialize e.g. Mermaid with the new theme // and re-parse the Mermaid code blocks. location.reload() } } const toggle = (value, list = []) => { const current = list.indexOf(value) const max = list.length - 1 let next = 0 if (current < max) { next = current + 1 } return next } ;(() => { applyTheme() })() document.addEventListener("DOMContentLoaded", () => { const colorThemeToggle = document.getElementById("gdoc-color-theme") const toggleColorTheme = () => { const lstore = Storage.namespace(THEME) const currentColorTheme = lstore.get("color-theme") || COLOR_THEME_AUTO const nextColorTheme = toggle(currentColorTheme, TOGGLE_COLOR_THEMES) lstore.set("color-theme", TOGGLE_COLOR_THEMES[nextColorTheme]) applyTheme(false) } colorThemeToggle.onclick = () => { toggleColorTheme() } colorThemeToggle.addEventListener("keydown", (event) => { if (event.key === "Enter") { toggleColorTheme() event.preventDefault() } }) }) ================================================ FILE: src/js/config.js ================================================ export const COLOR_THEME_DARK = "dark" export const COLOR_THEME_LIGHT = "light" export const COLOR_THEME_AUTO = "auto" export const THEME = "hugo-geekdoc" export const TOGGLE_COLOR_THEMES = [COLOR_THEME_AUTO, COLOR_THEME_DARK, COLOR_THEME_LIGHT] ================================================ FILE: src/js/index.js ================================================ import Clipboard from "clipboard" import "./accessibility.js" document.addEventListener("DOMContentLoaded", () => { const clipboard = new Clipboard(".clip") clipboard.on("success", (e) => { const { trigger, clearSelection } = e if (trigger.hasAttribute("data-copy-feedback")) { trigger.classList.add("gdoc-post__codecopy--success", "gdoc-post__codecopy--out") trigger.querySelector(".gdoc-icon.copy").classList.add("hidden") trigger.querySelector(".gdoc-icon.check").classList.remove("hidden") setTimeout(() => { trigger.classList.remove("gdoc-post__codecopy--success", "gdoc-post__codecopy--out") trigger.querySelector(".gdoc-icon.copy").classList.remove("hidden") trigger.querySelector(".gdoc-icon.check").classList.add("hidden") }, 3000) } clearSelection() }) document.querySelectorAll(".highlight").forEach(createCopyButton) }) const createCopyButton = (highlightDiv) => { const button = document.createElement("span") let codeSelector = "pre > code" if (highlightDiv.querySelector(".lntable")) { codeSelector = ".lntable .lntd:last-child pre > code" } const codeContainer = highlightDiv.querySelector(codeSelector) if (codeContainer !== null) { const codeContent = codeContainer.innerText.trim() button.classList.add("flex", "align-center", "justify-center", "clip", "gdoc-post__codecopy") button.type = "button" button.innerHTML = '' + '' button.setAttribute("data-clipboard-text", codeContent) button.setAttribute("data-copy-feedback", "Copied!") button.setAttribute("role", "button") button.setAttribute("aria-label", "Copy") highlightDiv.classList.add("gdoc-post__codecontainer") highlightDiv.insertBefore(button, highlightDiv.firstChild) } } ================================================ FILE: src/js/katex.js ================================================ import "katex/dist/katex.css" import renderMathInElement from "katex/dist/contrib/auto-render.mjs" renderMathInElement(document.body) ================================================ FILE: src/js/mermaid.js ================================================ import Storage from "store2" import { v4 as uuidv4 } from "uuid" import { COLOR_THEME_DARK, THEME, COLOR_THEME_AUTO } from "./config.js" import mermaid from "mermaid" document.addEventListener("DOMContentLoaded", () => { const lstore = Storage.namespace(THEME) const currentMode = lstore.get("color-theme") || COLOR_THEME_AUTO const darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)") let darkMode = false let theme = "default" if ( currentMode === COLOR_THEME_DARK || (currentMode === COLOR_THEME_AUTO && darkModeQuery.matches) ) { darkMode = true theme = "dark" } mermaid.initialize({ startOnLoad: false, flowchart: { useMaxWidth: true }, theme, themeVariables: { darkMode } }) document.querySelectorAll(".mermaid").forEach((el) => { const id = `graph-${uuidv4()}` mermaid.render(id, el.innerText).then(({ svg, bindFunctions }) => { el.innerHTML = svg bindFunctions?.(el) }) }) }) ================================================ FILE: src/js/search.js ================================================ import groupBy from "lodash/groupBy.js" import truncate from "lodash/truncate.js" import { Document, Charset } from "flexsearch" import { Validator } from "@cfworker/json-schema" document.addEventListener("DOMContentLoaded", function () { const input = document.querySelector("#gdoc-search-input") const results = document.querySelector("#gdoc-search-results") const basePath = urlPath(input ? input.dataset.siteBaseUrl : "") const lang = input ? input.dataset.siteLang : "" const configSchema = { type: "object", properties: { dataFile: { type: "string" }, indexConfig: { type: ["object", "null"] }, showParent: { type: "boolean" }, showDescription: { type: "boolean" } }, additionalProperties: false } const validator = new Validator(configSchema) if (!input) return getJson(combineURLs(basePath, `/search/${lang}.config.min.json`), function (searchConfig) { const validationResult = validator.validate(searchConfig) if (!validationResult.valid) throw AggregateError( validationResult.errors.map((err) => new Error(`Validation error: ${err.error}`)), "Schema validation failed" ) if (input) { input.addEventListener("focus", () => { init(input, searchConfig) }) input.addEventListener("keyup", () => { search(input, results, searchConfig) }) } }) }) function init(input, searchConfig) { input.removeEventListener("focus", init) const indexCfgDefaults = { tokenize: "forward", encoder: Charset.LatinBalance } const indexCfg = searchConfig.indexConfig ? searchConfig.indexConfig : indexCfgDefaults const dataUrl = searchConfig.dataFile indexCfg.document = { key: "id", index: ["title", "content", "description"], store: ["title", "href", "parent", "content", "description"] } const index = new Document(indexCfg) window.geekdocSearchIndex = index getJson(dataUrl, function (data) { data.forEach((obj) => { window.geekdocSearchIndex.add(obj) }) }) } function search(input, results, searchConfig) { const searchCfg = { enrich: true, limit: 5, highlight: { template: "$1", boundary: { before: 10, after: 20 } } } while (results.firstChild) { results.removeChild(results.firstChild) } if (!input.value) { return results.classList.remove("has-hits") } let searchHits = flattenHits(window.geekdocSearchIndex.search(input.value, searchCfg)) if (searchHits.length < 1) { return results.classList.remove("has-hits") } results.classList.add("has-hits") if (searchConfig.showParent === true) { searchHits = groupBy(searchHits, (hit) => hit.parent) } const items = [] if (searchConfig.showParent === true) { for (const section in searchHits) { const item = document.createElement("li"), title = item.appendChild(document.createElement("span")), subList = item.appendChild(document.createElement("ul")) if (!section) { title.remove() } title.classList.add("gdoc-search__section") title.textContent = section createLinks(searchHits[section], subList, searchConfig.showDescription) items.push(item) } } else { const item = document.createElement("li"), title = item.appendChild(document.createElement("span")), subList = item.appendChild(document.createElement("ul")) title.textContent = "Results" createLinks(searchHits, subList, searchConfig.showDescription) items.push(item) } items.forEach((item) => { results.appendChild(item) }) } /** * Creates links to given fields and either returns them in an array or attaches them to a target element * @param {Object} fields Page to which the link should point to * @param {HTMLElement} target Element to which the links should be attached * @returns {Array} If target is not specified, returns an array of built links */ function createLinks(pages, target, showDesc) { const items = [] for (const page of pages) { const item = document.createElement("li"), a = item.appendChild(document.createElement("a")), entry = a.appendChild(document.createElement("span")) a.href = page.href entry.classList.add("gdoc-search__entry--title") entry.textContent = page.title a.classList.add("gdoc-search__entry") if (showDesc === true) { const desc = a.appendChild(document.createElement("span")) desc.classList.add("gdoc-search__entry--description") if (page.highlight) { const parser = new DOMParser() const doc = parser.parseFromString( truncate(page.highlight, { length: 55, separator: " " }), "text/html" ) desc.innerHTML = doc.body.innerHTML } else { desc.textContent = truncate(page.description, { length: 55, separator: " " }) } } if (target) { target.appendChild(item) continue } items.push(item) } return items } function fetchErrors(response) { if (!response.ok) { throw Error(`Failed to fetch '${response.url}': ${response.statusText}`) } return response } function getJson(src, callback) { fetch(src) .then(fetchErrors) .then((response) => response.json()) .then((json) => callback(json)) .catch(function (error) { if (error instanceof AggregateError) { console.error(error.message) error.errors.forEach((element) => { console.error(element) }) } else { console.error(error) } }) } function flattenHits(results) { const items = [] const map = new Map() for (const field of results) { for (const page of field.result) { if (!map.has(page.doc.href)) { map.set(page.doc.href, true) if (page.highlight) { page.doc.highlight = page.highlight } items.push(page.doc) } } } return items } function urlPath(rawURL) { const parser = document.createElement("a") parser.href = rawURL return parser.pathname } /** * Part of [axios](https://github.com/axios/axios/blob/master/lib/helpers/combineURLs.js). * Creates a new URL by combining the specified URLs * * @param {string} baseURL The base URL * @param {string} relativeURL The relative URL * @returns {string} The combined URL */ function combineURLs(baseURL, relativeURL) { return relativeURL ? `${baseURL.replace(/\/+$/, "")}/${relativeURL.replace(/^\/+/, "")}` : baseURL } ================================================ FILE: src/sass/_asciidoc.scss ================================================ @use "sass:color"; @use "defaults"; .admonitionblock { $root: &; margin: defaults.$padding-16 0; padding: 0; border: defaults.$border-1 solid var(--accent-color); border-left: defaults.$border-4 solid var(--accent-color); border-radius: defaults.$border-radius; @each $name, $color in defaults.$hint-colors { &.#{$name} { border-color: $color; td.icon { background-color: color.adjust($color, $alpha: -0.9); border-start-start-radius: inherit; border-start-end-radius: inherit; position: relative; z-index: -10; outline: color.adjust($color, $alpha: -0.9); } } } .table-wrap { margin: 0; } table { margin: 0 !important; padding: 0 !important; tr { border: 0 !important; } td { display: block; padding: defaults.$padding-4 defaults.$padding-16 !important; &:first-child { background-color: color.scale(defaults.$gray-600, $alpha: -95%); font-weight: bold; &.icon { margin-left: -5px; @each $name, $icon in defaults.$hint-icons { i.fa.icon-#{$name} { width: defaults.$font-size-24; height: defaults.$font-size-24; position: relative; &::before { content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: defaults.$font-size-24; height: defaults.$font-size-24; mask-image: url(img/geekdoc-stack.svg##{$icon}); mask-repeat: no-repeat; mask-size: contain; background-color: var(--body-font-color); } &::after { color: var(--body-font-color); content: attr(title); font-style: normal; padding-left: defaults.$padding-32; } } } } } } } } ================================================ FILE: src/sass/_base.scss ================================================ @use "sass:meta"; @use "sass:map"; @use "color_mode"; @use "defaults"; :root { --code-max-height: none; --header-font-family: #{meta.inspect(defaults.$header-font-family)}; --body-font-family: #{meta.inspect(defaults.$body-font-family)}; --code-font-family: #{meta.inspect(defaults.$code-font-family)}; } :root, :root[color-theme="light"] { @include color_mode.color_theme_light; @include color_mode.code_theme_light; } @media (prefers-color-scheme: light) { :root { @include color_mode.color_theme_light; @include color_mode.code_theme_light; } } :root[color-theme="dark"] { @include color_mode.color_theme_dark; @include color_mode.code_theme_dark; } :root[code-theme="dark"] { @include color_mode.code_theme_dark; } @media (prefers-color-scheme: dark) { :root { @include color_mode.color_theme_dark; @include color_mode.code_theme_dark; } } html { font-size: defaults.$font-size-base; letter-spacing: 0.33px; scroll-behavior: smooth; &.color-toggle-hidden { #gdoc-color-theme { display: none; } } &.color-toggle-light { #gdoc-color-theme { .gdoc_brightness_light { display: inline-block; } .gdoc_brightness_auto, .gdoc_brightness_dark { display: none; } } } &.color-toggle-dark { #gdoc-color-theme { .gdoc_brightness_dark { display: inline-block; } .gdoc_brightness_auto, .gdoc_brightness_light { display: none; } } } &.color-toggle-auto { #gdoc-color-theme { .gdoc_brightness_light { display: none; } .gdoc_brightness_dark { display: none; } .gdoc_brightness_auto { display: inline-block; } } } } html, body { min-width: defaults.$body-min-width; overflow-x: hidden; } body { text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; box-sizing: border-box; * { box-sizing: inherit; } #gdoc-to-main { position: absolute; margin: defaults.$padding-8 0; padding: defaults.$padding-8; display: inline-block; background-color: var(--accent-color-lite); border-radius: defaults.$border-radius; border: defaults.$border-1 solid var(--accent-color); transform: translateY(0); transition: transform 250ms ease-in; &:not(:focus) { transform: translateY(-#{defaults.$padding-64}); } } } h1, h2, h3, h4, h5, h6 { font-weight: defaults.$body-font-weight; display: flex; align-items: center; } h4, h5, h6 { font-size: defaults.$font-size-16 !important; } a { text-decoration: none; color: var(--link-color); &:hover { text-decoration: underline; } &:visited { color: var(--link-color-visited); } } i.gdoc-icon { font-family: "GeekdocIcons"; font-style: normal; } img { vertical-align: middle; } #gdoc-color-theme { cursor: pointer; } .fake-link:hover { background-image: linear-gradient(var(--link-color), var(--link-color)); background-position: 0 100%; background-size: 100% 1px; background-repeat: no-repeat; text-decoration: none; } .wrapper { display: flex; flex-direction: column; min-height: 100vh; color: var(--body-font-color); background: var(--body-background); font-weight: defaults.$body-font-weight; } .container { width: 100%; max-width: defaults.$container-max-width; margin: 0 auto; padding: defaults.$padding-20; } svg.gdoc-icon { display: inline-block; width: defaults.$font-size-20; height: defaults.$font-size-20; vertical-align: middle; stroke-width: 0; stroke: currentColor; fill: currentColor; position: relative; } .gdoc-header { background: var(--header-background); color: var(--header-font-color); border-bottom: 0.3em solid var(--footer-background); &__link, &__link:visited { color: var(--header-font-color); } &__link:hover { text-decoration: none; } svg.gdoc-icon { width: defaults.$font-size-32; height: defaults.$font-size-32; } } .gdoc-brand { &__img { width: defaults.$padding-32; height: defaults.$padding-32; } &__title { font-size: defaults.$font-size-24; line-height: defaults.$font-size-24; } &__subtitle { font-size: defaults.$font-size-12; } } .gdoc-menu-header { &__items { display: flex; > span { margin-left: defaults.$padding-8; } } &__control, &__home { display: none; svg.gdoc-icon { cursor: pointer; } } } .gdoc-nav { flex: 0 0 defaults.$menu-width; nav { width: defaults.$menu-width; padding: defaults.$padding-16 defaults.$padding-32 defaults.$padding-16 0; > ul > li > * { font-weight: normal; } section { margin-top: defaults.$padding-32; } } &__control { display: none; margin: 0; padding: 0; svg.gdoc-icon { cursor: pointer; } svg.gdoc-icon.gdoc_menu { display: inline-block; } svg.gdoc-icon.gdoc_arrow_back { display: none; } } &__list { padding-left: defaults.$padding-16; margin: 0; padding: 0; list-style: none; user-select: none; ul { padding-left: defaults.$padding-16; } li { margin: defaults.$padding-12 0; } svg.gdoc-icon { margin-right: defaults.$padding-4; } } &__toggle { display: none; & ~ label { cursor: pointer; svg.gdoc-icon.toggle { width: defaults.$font-size-16; height: defaults.$font-size-16; } } &:not(:checked) { & ~ ul, & ~ label svg.gdoc-icon.gdoc_keyboard_arrow_down { display: none; } & ~ label svg.gdoc-icon.gdoc_keyboard_arrow_left { display: block; } } &:checked { & ~ ul, & ~ label svg.gdoc-icon.gdoc_keyboard_arrow_down { display: block; } & ~ label svg.gdoc-icon.gdoc_keyboard_arrow_left { display: none; } } } &--main > ul > li > span, &--main > ul > li > span > a, &--main > ul > li > label, &--main > ul > li > label > a { font-weight: bold; } } .gdoc-nav__entry, .gdoc-language__entry { flex: 1; color: var(--body-font-color); &:hover, &.is-active { text-decoration: underline; text-decoration-style: dashed !important; } &:visited { color: var(--body-font-color); } } .gdoc-search__list, .gdoc-language__list { background: var(--body-background); border-radius: defaults.$border-radius; box-shadow: 0 1px 3px 0 var(--accent-color), 0 1px 2px 0 var(--accent-color-lite); position: absolute; margin: 0; padding: defaults.$padding-8 defaults.$padding-4 !important; list-style: none; top: calc(100% + #{defaults.$padding-8}); z-index: 2; } .gdoc-page { min-width: calc(defaults.$body-min-width - defaults.$padding-32); flex-grow: 1; padding: defaults.$padding-16 0; h1, h2, h3, h4, h5, h6 { font-weight: 600; } &__header, &__footer { margin-bottom: defaults.$padding-24; svg.gdoc-icon { color: var(--control-icons); } a, a:visited { color: var(--link-color); } } &__header { background: var(--accent-color-lite); padding: defaults.$padding-8 defaults.$padding-16; border-radius: defaults.$border-radius; } &__nav { &:hover { background-image: linear-gradient(var(--link-color), var(--link-color)); background-position: 0 100%; background-size: 100% 1px; background-repeat: no-repeat; } } &__anchorwrap { gap: 0.5em; &:hover .gdoc-page__anchor svg.gdoc-icon { color: var(--control-icons); } } &__anchor { svg.gdoc-icon { width: 1.85em; height: 1.85em; color: transparent; transition: color 0.2s ease-in-out; } &:focus { svg.gdoc-icon { color: var(--control-icons); } } } &__footer { margin-top: defaults.$padding-32; a:hover { text-decoration: none; } } } .gdoc-post { word-wrap: break-word; border-top: 1px dashed defaults.$gray-600; padding: defaults.$padding-32 0; &:first-of-type { padding-top: 0; } &__header { h1 { margin-top: 0; } a, a:visited { color: var(--body-font-color); text-decoration: none; } a:hover { background: none; text-decoration: underline; color: var(--body-font-color); } } &:first-child { border-top: 0; h1 { margin-top: 0; } } &__readmore { margin: defaults.$padding-32 0; a, a:hover, a:visited { color: var(--link-color); text-decoration: none !important; } } &__meta { span svg.gdoc-icon { margin-left: -5px; } > span { margin: defaults.$padding-4 0; &:not(:last-child) { margin-right: defaults.$padding-8; } } svg.gdoc-icon { font-size: defaults.$font-size-20; } .gdoc-button { margin: 0 defaults.$padding-2 0 0; } &--head { margin-bottom: defaults.$padding-32; } } &__codecontainer { position: relative; &:hover > .gdoc-post__codecopy { opacity: 1; visibility: visible; pointer-events: auto; } } &__codecopy { opacity: 0; visibility: hidden; transition: opacity 0.2s ease, visibility 0.2s ease; pointer-events: none; position: absolute; top: defaults.$padding-8; right: defaults.$padding-8; border: defaults.$border-2 solid var(--code-copy-border-color); border-radius: defaults.$border-radius; background: var(--code-copy-background); width: defaults.$padding-32; height: defaults.$padding-32; svg.gdoc-icon { top: 0; width: defaults.$font-size-20; height: defaults.$font-size-20; color: var(--code-copy-font-color); } &:hover { cursor: pointer; } &--success { border-color: var(--code-copy-success-color); svg.gdoc-icon { color: var(--code-copy-success-color); } } &--out { transition: visibility 2s ease-out; } } } .gdoc-footer { background: var(--footer-background); color: var(--footer-font-color); .fake-link { text-decoration: none; &:hover { background-image: linear-gradient(var(--footer-link-color), var(--footer-link-color)); } } &__item { line-height: defaults.$padding-32; &--row { margin-right: defaults.$padding-16; } } &__link { text-decoration: underline; color: var(--footer-link-color); &:hover { text-decoration: none; } &:visited { color: var(--footer-link-color-visited); } } } .gdoc-search { position: relative; svg.gdoc-icon { position: absolute; left: defaults.$padding-8; color: var(--control-icons); width: defaults.$font-size-20; height: defaults.$font-size-20; } &::after { display: block; content: ""; clear: both; } &__input { width: 100%; padding: defaults.$padding-8; padding-left: defaults.$padding-32; transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; border: 1px solid transparent; border-radius: defaults.$border-radius; background: var(--accent-color-lite); color: var(--body-font-color); &:focus { outline: none !important; border: 1px solid var(--accent-color); } } &__list { visibility: hidden; left: 0; width: 100%; ul { list-style: none; padding-left: 0; } > li > span { font-weight: bold; } > li + li { margin-top: defaults.$padding-4; } svg.gdoc-icon { margin-right: defaults.$padding-4; } } &__section { display: flex; flex-direction: column; padding: defaults.$padding-4 !important; } &__entry { display: flex; flex-direction: column; color: var(--body-font-color); padding: defaults.$padding-4 !important; border-radius: defaults.$border-radius; &:hover, &.is-active { background: var(--accent-color-lite); text-decoration: none; .gdoc-search__entry--title { text-decoration-style: dashed !important; text-decoration: underline; } } &:visited { color: var(--body-font-color); } &--description { font-size: defaults.$font-size-14; font-style: italic; } } &:focus-within &__list.has-hits, &__list.has-hits:hover { visibility: visible; } } .gdoc-language { &__selector { position: relative; list-style: none; user-select: none; cursor: pointer; margin: 0; padding: 0; width: 100%; &:focus, &:focus-within, &:active { .gdoc-language__list { display: block; } } } &__list { display: none; right: 0; width: auto; white-space: nowrap; } } .gdoc-paging { padding: defaults.$padding-16 0; &__item { flex: 1 1 0; a:visited { color: var(--link-color); } a:hover, a:visited:hover { background: var(--link-color); color: defaults.$gray-100; } &--next { text-align: right; } &--prev { text-align: left; } } } .gdoc-error { padding: defaults.$padding-96 defaults.$padding-16; margin: 0 auto; max-width: 45em; svg.gdoc-icon { width: defaults.$font-size-128; height: defaults.$font-size-128; color: var(--body-font-color); } &__link, &__link:visited { text-decoration: underline; color: var(--link-color); } &__message { padding-left: defaults.$padding-64; } &__line { padding: defaults.$padding-8 0; } &__title { font-size: defaults.$font-size-64; } &__code { font-weight: bolder; } } .gdoc-toc { margin: defaults.$padding-16 0; li { margin: defaults.$padding-4 0; } // Classes to hide nested levels of ToC/Menu &__level--1 ul ul, &__level--2 ul ul ul, &__level--3 ul ul ul ul, &__level--4 ul ul ul ul ul, &__level--5 ul ul ul ul ul ul, &__level--6 ul ul ul ul ul ul ul { display: none; } a, a:visited { text-decoration: none !important; color: var(--link-color); } } // Responsive styles .gdoc-nav nav, .gdoc-page, .markdown { transition: 0.2s ease-in-out; transition-property: transform, margin-left, opacity; will-change: transform, margin-left; } // Breadcrumbs styles .breadcrumb { display: inline; padding: 0; margin: 0; li { display: inline; } } ================================================ FILE: src/sass/_chroma_base.scss ================================================ @use "defaults"; @mixin chroma_base { .chroma { color: var(--code-font-color); } .chroma .lntable td:nth-child(2) code .hl { width: auto; margin-left: -0.5em; padding: 0 0.5em; } .highlight { pre.chroma { width: 100%; overflow: auto; max-height: var(--code-max-height); } } /* LineTable */ .chroma .lntable { border-radius: defaults.$border-radius; border-spacing: 0; padding: 0; margin: 0; width: 100%; display: block; max-height: var(--code-max-height); overflow: auto; pre.chroma { max-height: none; border-radius: 0; margin: 0; } } .chroma .lntable td:first-child { code { background-color: var(--code-accent-color-lite); font-size: defaults.$font-size-12; padding-left: 0; padding-right: 0; border-radius: 0; } } .chroma .lntable td:nth-child(2) { width: 100%; margin-left: defaults.$padding-32; } } ================================================ FILE: src/sass/_chroma_dark.scss ================================================ @use "chroma_base"; @mixin chroma_dark { /* Theme: Dracula */ /* Background */ @include chroma_base.chroma_base; /* Other */ .chroma .x { color: inherit; } /* Error */ .chroma .err { color: inherit; } /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } /* LineHighlight */ .chroma .hl { display: block; width: 100%; background-color: #4f1605; } /* LineNumbersTable */ .chroma .lnt { padding: 0 0.8em; } /* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; color: #b3b3b3; } /* Keyword */ .chroma .k { color: #ff79c6; } /* KeywordConstant */ .chroma .kc { color: #ff79c6; } /* KeywordDeclaration */ .chroma .kd { color: #8be9fd; font-style: italic; } /* KeywordNamespace */ .chroma .kn { color: #ff79c6; } /* KeywordPseudo */ .chroma .kp { color: #ff79c6; } /* KeywordReserved */ .chroma .kr { color: #ff79c6; } /* KeywordType */ .chroma .kt { color: #8be9fd; } /* Name */ .chroma .n { color: inherit; } /* NameAttribute */ .chroma .na { color: #50fa7b; } /* NameBuiltin */ .chroma .nb { color: #8be9fd; font-style: italic; } /* NameBuiltinPseudo */ .chroma .bp { color: inherit; } /* NameClass */ .chroma .nc { color: #50fa7b; } /* NameConstant */ .chroma .no { color: inherit; } /* NameDecorator */ .chroma .nd { color: inherit; } /* NameEntity */ .chroma .ni { color: inherit; } /* NameException */ .chroma .ne { color: inherit; } /* NameFunction */ .chroma .nf { color: #50fa7b; } /* NameFunctionMagic */ .chroma .fm { color: inherit; } /* NameLabel */ .chroma .nl { color: #8be9fd; font-style: italic; } /* NameNamespace */ .chroma .nn { color: inherit; } /* NameOther */ .chroma .nx { color: inherit; } /* NameProperty */ .chroma .py { color: inherit; } /* NameTag */ .chroma .nt { color: #ff79c6; } /* NameVariable */ .chroma .nv { color: #8be9fd; font-style: italic; } /* NameVariableClass */ .chroma .vc { color: #8be9fd; font-style: italic; } /* NameVariableGlobal */ .chroma .vg { color: #8be9fd; font-style: italic; } /* NameVariableInstance */ .chroma .vi { color: #8be9fd; font-style: italic; } /* NameVariableMagic */ .chroma .vm { color: inherit; } /* Literal */ .chroma .l { color: inherit; } /* LiteralDate */ .chroma .ld { color: inherit; } /* LiteralString */ .chroma .s { color: #f1fa8c; } /* LiteralStringAffix */ .chroma .sa { color: #f1fa8c; } /* LiteralStringBacktick */ .chroma .sb { color: #f1fa8c; } /* LiteralStringChar */ .chroma .sc { color: #f1fa8c; } /* LiteralStringDelimiter */ .chroma .dl { color: #f1fa8c; } /* LiteralStringDoc */ .chroma .sd { color: #f1fa8c; } /* LiteralStringDouble */ .chroma .s2 { color: #f1fa8c; } /* LiteralStringEscape */ .chroma .se { color: #f1fa8c; } /* LiteralStringHeredoc */ .chroma .sh { color: #f1fa8c; } /* LiteralStringInterpol */ .chroma .si { color: #f1fa8c; } /* LiteralStringOther */ .chroma .sx { color: #f1fa8c; } /* LiteralStringRegex */ .chroma .sr { color: #f1fa8c; } /* LiteralStringSingle */ .chroma .s1 { color: #f1fa8c; } /* LiteralStringSymbol */ .chroma .ss { color: #f1fa8c; } /* LiteralNumber */ .chroma .m { color: #bd93f9; } /* LiteralNumberBin */ .chroma .mb { color: #bd93f9; } /* LiteralNumberFloat */ .chroma .mf { color: #bd93f9; } /* LiteralNumberHex */ .chroma .mh { color: #bd93f9; } /* LiteralNumberInteger */ .chroma .mi { color: #bd93f9; } /* LiteralNumberIntegerLong */ .chroma .il { color: #bd93f9; } /* LiteralNumberOct */ .chroma .mo { color: #bd93f9; } /* Operator */ .chroma .o { color: #ff79c6; } /* OperatorWord */ .chroma .ow { color: #ff79c6; } /* Punctuation */ .chroma .p { color: inherit; } /* Comment */ .chroma .c { color: #96a6d8; } /* CommentHashbang */ .chroma .ch { color: #96a6d8; } /* CommentMultiline */ .chroma .cm { color: #96a6d8; } /* CommentSingle */ .chroma .c1 { color: #96a6d8; } /* CommentSpecial */ .chroma .cs { color: #96a6d8; } /* CommentPreproc */ .chroma .cp { color: #ff79c6; } /* CommentPreprocFile */ .chroma .cpf { color: #ff79c6; } /* Generic */ .chroma .g { color: inherit; } /* GenericDeleted */ .chroma .gd { color: #d98f90; } /* GenericEmph */ .chroma .ge { text-decoration: underline; } /* GenericError */ .chroma .gr { color: inherit; } /* GenericHeading */ .chroma .gh { font-weight: bold; color: inherit; } /* GenericInserted */ .chroma .gi { font-weight: bold; } /* GenericOutput */ .chroma .go { color: #8f9ea8; } /* GenericPrompt */ .chroma .gp { color: inherit; } /* GenericStrong */ .chroma .gs { color: inherit; } /* GenericSubheading */ .chroma .gu { font-weight: bold; } /* GenericTraceback */ .chroma .gt { color: inherit; } /* GenericUnderline */ .chroma .gl { text-decoration: underline; } /* TextWhitespace */ .chroma .w { color: inherit; } } ================================================ FILE: src/sass/_chroma_light.scss ================================================ @use "chroma_base"; @mixin chroma_github { /* Theme: GitHub */ /* Background */ @include chroma_base.chroma_base; /* Other */ .chroma .x { color: inherit; } /* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2; } /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } /* LineHighlight */ .chroma .hl { display: block; width: 100%; background-color: #ffffcc; } /* LineNumbersTable */ .chroma .lnt { padding: 0 0.8em; } /* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; } /* Keyword */ .chroma .k { color: #000000; font-weight: bold; } /* KeywordConstant */ .chroma .kc { color: #000000; font-weight: bold; } /* KeywordDeclaration */ .chroma .kd { color: #000000; font-weight: bold; } /* KeywordNamespace */ .chroma .kn { color: #000000; font-weight: bold; } /* KeywordPseudo */ .chroma .kp { color: #000000; font-weight: bold; } /* KeywordReserved */ .chroma .kr { color: #000000; font-weight: bold; } /* KeywordType */ .chroma .kt { color: #445588; font-weight: bold; } /* Name */ .chroma .n { color: inherit; } /* NameAttribute */ .chroma .na { color: #006767; } /* NameBuiltin */ .chroma .nb { color: #556165; } /* NameBuiltinPseudo */ .chroma .bp { color: #676767; } /* NameClass */ .chroma .nc { color: #445588; font-weight: bold; } /* NameConstant */ .chroma .no { color: #006767; } /* NameDecorator */ .chroma .nd { color: #3c5d5d; font-weight: bold; } /* NameEntity */ .chroma .ni { color: #800080; } /* NameException */ .chroma .ne { color: #990000; font-weight: bold; } /* NameFunction */ .chroma .nf { color: #990000; font-weight: bold; } /* NameFunctionMagic */ .chroma .fm { color: inherit; } /* NameLabel */ .chroma .nl { color: #990000; font-weight: bold; } /* NameNamespace */ .chroma .nn { color: #555555; } /* NameOther */ .chroma .nx { color: inherit; } /* NameProperty */ .chroma .py { color: inherit; } /* NameTag */ .chroma .nt { color: #000080; } /* NameVariable */ .chroma .nv { color: #006767; } /* NameVariableClass */ .chroma .vc { color: #006767; } /* NameVariableGlobal */ .chroma .vg { color: #006767; } /* NameVariableInstance */ .chroma .vi { color: #006767; } /* NameVariableMagic */ .chroma .vm { color: inherit; } /* Literal */ .chroma .l { color: inherit; } /* LiteralDate */ .chroma .ld { color: inherit; } /* LiteralString */ .chroma .s { color: #dd1144; } /* LiteralStringAffix */ .chroma .sa { color: #dd1144; } /* LiteralStringBacktick */ .chroma .sb { color: #dd1144; } /* LiteralStringChar */ .chroma .sc { color: #dd1144; } /* LiteralStringDelimiter */ .chroma .dl { color: #dd1144; } /* LiteralStringDoc */ .chroma .sd { color: #dd1144; } /* LiteralStringDouble */ .chroma .s2 { color: #dd1144; } /* LiteralStringEscape */ .chroma .se { color: #dd1144; } /* LiteralStringHeredoc */ .chroma .sh { color: #dd1144; } /* LiteralStringInterpol */ .chroma .si { color: #dd1144; } /* LiteralStringOther */ .chroma .sx { color: #dd1144; } /* LiteralStringRegex */ .chroma .sr { color: #009926; } /* LiteralStringSingle */ .chroma .s1 { color: #dd1144; } /* LiteralStringSymbol */ .chroma .ss { color: #990073; } /* LiteralNumber */ .chroma .m { color: #027e83; } /* LiteralNumberBin */ .chroma .mb { color: #027e83; } /* LiteralNumberFloat */ .chroma .mf { color: #027e83; } /* LiteralNumberHex */ .chroma .mh { color: #027e83; } /* LiteralNumberInteger */ .chroma .mi { color: #027e83; } /* LiteralNumberIntegerLong */ .chroma .il { color: #027e83; } /* LiteralNumberOct */ .chroma .mo { color: #027e83; } /* Operator */ .chroma .o { color: #000000; font-weight: bold; } /* OperatorWord */ .chroma .ow { color: #000000; font-weight: bold; } /* Punctuation */ .chroma .p { color: inherit; } /* Comment */ .chroma .c { color: #676765; font-style: italic; } /* CommentHashbang */ .chroma .ch { color: #676765; font-style: italic; } /* CommentMultiline */ .chroma .cm { color: #676765; font-style: italic; } /* CommentSingle */ .chroma .c1 { color: #676765; font-style: italic; } /* CommentSpecial */ .chroma .cs { color: #676767; font-weight: bold; font-style: italic; } /* CommentPreproc */ .chroma .cp { color: #676767; font-weight: bold; font-style: italic; } /* CommentPreprocFile */ .chroma .cpf { color: #676767; font-weight: bold; font-style: italic; } /* Generic */ .chroma .g { color: inherit; } /* GenericDeleted */ .chroma .gd { color: #000000; background-color: #ffdddd; } /* GenericEmph */ .chroma .ge { color: #000000; font-style: italic; } /* GenericError */ .chroma .gr { color: #aa0000; } /* GenericHeading */ .chroma .gh { color: #676767; } /* GenericInserted */ .chroma .gi { color: #000000; background-color: #ddffdd; } /* GenericOutput */ .chroma .go { color: #6f6f6f; } /* GenericPrompt */ .chroma .gp { color: #555555; } /* GenericStrong */ .chroma .gs { font-weight: bold; } /* GenericSubheading */ .chroma .gu { color: #5f5f5f; } /* GenericTraceback */ .chroma .gt { color: #aa0000; } /* GenericUnderline */ .chroma .gl { text-decoration: underline; } /* TextWhitespace */ .chroma .w { color: #bbbbbb; } } ================================================ FILE: src/sass/_color_mode.scss ================================================ @use "sass:color"; @use "sass:map"; @use "chroma_dark"; @use "chroma_light"; @use "defaults"; @mixin color_theme_light { --header-background: #{defaults.$main-color}; --header-font-color: #{defaults.$white}; --body-background: #{defaults.$body-background}; --body-font-color: #{defaults.$body-font-color}; --mark-color: #{defaults.$mark-color}; --button-background: #{color.scale(defaults.$main-color, $lightness: 15%)}; --button-border-color: #{defaults.$main-color}; --link-color: #{defaults.$link-color}; --link-color-visited: #{defaults.$link-color-visited}; --accent-color: #{defaults.$gray-200}; --accent-color-lite: #{defaults.$gray-100}; --control-icons: #{color.scale(defaults.$body-font-color, $lightness: 40%)}; --footer-background: #{defaults.$second-color}; --footer-font-color: #{defaults.$white}; --footer-link-color: #{defaults.$link-color-footer}; --footer-link-color-visited: #{defaults.$link-color-footer}; .dark-mode-dim .gdoc-markdown { img { filter: none; } } } @mixin color_theme_dark { --header-background: #{defaults.$main-color}; --header-font-color: #{defaults.$white}; --body-background: #{defaults.$body-background-dark}; --body-font-color: #{color.scale(defaults.$body-background-dark, $lightness: 70%)}; --mark-color: #{defaults.$mark-color}; --button-background: #{color.scale(defaults.$main-color, $lightness: 15%)}; --button-border-color: #{defaults.$main-color}; --link-color: #{defaults.$link-color-dark}; --link-color-visited: #{defaults.$link-color-visited-dark}; --accent-color: #{color.scale(defaults.$body-background-dark, $lightness: -30%)}; --accent-color-lite: #{color.scale(defaults.$body-background-dark, $lightness: -15%)}; --control-icons: #{color.scale(defaults.$body-font-color, $lightness: 40%)}; --footer-background: #{defaults.$second-color}; --footer-font-color: #{defaults.$white}; --footer-link-color: #{defaults.$link-color-footer}; --footer-link-color-visited: #{defaults.$link-color-footer}; .dark-mode-dim { .gdoc-markdown img { filter: brightness(0.75) grayscale(0.2); } } } @mixin code_theme_dark { @include chroma_dark.chroma_dark; & { --code-background: #{defaults.$code-background-dark}; --code-accent-color: #{color.scale(defaults.$code-background-dark, $lightness: -30%)}; --code-accent-color-lite: #{color.scale(defaults.$code-background-dark, $lightness: -15%)}; --code-font-color: #{defaults.$gray-300}; --code-copy-background: #{defaults.$code-background-dark}; --code-copy-font-color: #{color.scale(defaults.$code-font-color-dark, $lightness: -15%)}; --code-copy-border-color: #{color.scale(defaults.$code-font-color-dark, $lightness: -20%)}; --code-copy-success-color: #{color.scale(map.get(defaults.$hint-colors, "ok"), $alpha: -55%)}; } } @mixin code_theme_light { @include chroma_light.chroma_github; & { --code-background: #{defaults.$code-background}; --code-accent-color: #{color.scale(defaults.$code-background, $lightness: -45%)}; --code-accent-color-lite: #{color.scale(defaults.$code-background, $lightness: -15%)}; --code-font-color: #{defaults.$gray-700}; --code-copy-background: #{defaults.$code-background}; --code-copy-font-color: #{defaults.$gray-500}; --code-copy-border-color: #{defaults.$gray-400}; --code-copy-success-color: #{map.get(defaults.$hint-colors, "ok")}; } } ================================================ FILE: src/sass/_defaults.scss ================================================ @use "sass:color"; // Used in layout $padding-2: 0.125rem !default; $padding-4: 0.25rem !default; $padding-8: 0.5rem !default; $padding-12: 0.75rem !default; $padding-16: 1rem !default; $padding-20: 1.25rem !default; $padding-24: 1.5rem !default; $padding-32: 2rem !default; $padding-48: 3rem !default; $padding-64: 4rem !default; $padding-96: 6rem !default; $font-size-base: 16px !default; $font-size-12: 0.75rem !default; $font-size-14: 0.875rem !default; $font-size-16: 1rem !default; $font-size-20: 1.25rem !default; $font-size-24: 1.5rem !default; $font-size-32: 2rem !default; $font-size-64: 4rem !default; $font-size-96: 6rem !default; $font-size-128: 8rem !default; $border-1: 1px !default; $border-2: 1.5px !default; $border-4: 3px !default; $border-radius: 0.3rem !default; // Grayscale $white: rgba(255, 255, 255, 1) !default; $gray-100: rgba(244, 246, 247, 1) !default; $gray-200: rgba(217, 219, 221, 1) !default; $gray-300: rgba(189, 192, 195, 1) !default; $gray-400: rgba(162, 165, 169, 1) !default; $gray-500: rgba(134, 137, 142, 1) !default; $gray-600: rgba(107, 110, 116, 1) !default; $gray-700: rgba(79, 83, 90, 1) !default; $gray-800: rgba(52, 56, 64, 1) !default; $black: rgba(0, 0, 0, 1) !default; $link-color: rgba(10, 83, 154, 1) !default; $link-color-visited: rgba(119, 73, 191, 1) !default; $link-color-footer: rgba(246, 107, 14, 1) !default; $body-background: white !default; $body-font-family: "Liberation Sans", sans-serif !default; $body-font-color: $gray-800 !default; $body-font-weight: normal !default; $body-min-width: 20rem !default; $code-font-family: "Liberation Mono", monospace !default; $code-font-color: rgba(70, 70, 70, 1) !default; $code-font-color-dark: rgba(185, 185, 185, 1) !default; $container-max-width: 82rem !default; $main-color: rgba(32, 83, 117, 1) !default; $second-color: rgba(17, 43, 60, 1) !default; $mark-color: rgba(255, 171, 0, 1) !default; $body-background-dark: color.mix(color.invert($body-background, 75%), $second-color) !default; $body-font-color-dark: $gray-100 !default; $link-color-dark: rgba(110, 168, 212, 1) !default; $link-color-visited-dark: rgba(186, 142, 240) !default; $code-background: $gray-100 !default; $code-background-dark: color.scale($body-background-dark, $lightness: -15%) !default; $header-font-family: "Metropolis", sans-serif !default; $header-height: 3.5rem !default; $menu-width: 18rem !default; $sm-breakpoint: $menu-width + $body-min-width + 3rem !default; // Panel colors $hint-colors: ( info: rgba(0, 145, 234, 1), note: rgba(0, 145, 234, 1), ok: rgba(0, 200, 83, 1), tip: rgba(0, 200, 83, 1), important: rgba(255, 171, 0, 1), caution: rgba(115, 0, 211, 1), danger: rgba(213, 0, 0, 1), warning: rgba(213, 0, 0, 1) ) !default; // Panel colors $hint-icons: ( info: "gdoc_info_outline", note: "gdoc_info_outline", ok: "gdoc_check_circle_outline", tip: "gdoc_check_circle_outline", important: "gdoc_error_outline", caution: "gdoc_dangerous", danger: "gdoc_fire", warning: "gdoc_fire" ) !default; ================================================ FILE: src/sass/_fonts.scss ================================================ @font-face { font-family: "Liberation Sans"; src: url("fonts/LiberationSans-Bold.woff2") format("woff2"), url("fonts/LiberationSans-Bold.woff") format("woff"); font-weight: bold; font-style: normal; font-display: swap; } @font-face { font-family: "Liberation Sans"; src: url("fonts/LiberationSans-BoldItalic.woff2") format("woff2"), url("fonts/LiberationSans-BoldItalic.woff") format("woff"); font-weight: bold; font-style: italic; font-display: swap; } @font-face { font-family: "Liberation Sans"; src: url("fonts/LiberationSans-Italic.woff2") format("woff2"), url("fonts/LiberationSans-Italic.woff") format("woff"); font-weight: normal; font-style: italic; font-display: swap; } @font-face { font-family: "Liberation Sans"; src: url("fonts/LiberationSans.woff2") format("woff2"), url("fonts/LiberationSans.woff") format("woff"); font-weight: normal; font-style: normal; font-display: swap; } @font-face { font-family: "Liberation Mono"; src: url("fonts/LiberationMono.woff2") format("woff2"), url("fonts/LiberationMono.woff") format("woff"); font-weight: normal; font-style: normal; font-display: swap; } @font-face { font-family: "Metropolis"; src: url("fonts/Metropolis.woff2") format("woff2"), url("fonts/Metropolis.woff") format("woff"); font-weight: normal; font-style: normal; font-display: swap; } @font-face { font-family: "GeekdocIcons"; src: url("fonts/GeekdocIcons.woff2") format("woff2"), url("fonts/GeekdocIcons.woff") format("woff"); font-weight: normal; font-style: normal; font-display: swap; } body { font-family: var(--body-font-family); } code, .gdoc-error__title { font-family: var(--code-font-family); } .gdoc-header { font-family: var(--header-font-family); } ================================================ FILE: src/sass/_markdown.scss ================================================ @use "defaults"; .gdoc-markdown { line-height: 1.6rem; h1, h2, h3, h4, h5, h6 { font-weight: 600; > code { border-top: defaults.$border-4 solid var(--accent-color); font-size: defaults.$font-size-12 !important; } } h4, h5, h6 { > code { font-size: defaults.$font-size-14 !important; } } b, optgroup, strong { font-weight: bolder; } a, &__link { text-decoration: underline; border-bottom: defaults.$border-1 solid transparent; line-height: normal; &:hover { text-decoration: none; } } &__link--raw { text-decoration: none !important; color: defaults.$body-font-color !important; &:hover { text-decoration: none !important; } &:visited { color: defaults.$body-font-color !important; } } &__link--code { text-decoration: underline; code { color: inherit !important; } &:hover { background: none; color: var(--link-color) !important; text-decoration: none; } &:visited, &:visited:hover { color: var(--link-color-visited) !important; } } &__figure { padding: defaults.$padding-4; margin: defaults.$padding-16 0; background-color: var(--accent-color); display: table; border-top-left-radius: defaults.$border-radius; border-top-right-radius: defaults.$border-radius; &--round, &--round img { border-radius: 50% !important; } figcaption { display: table-caption; caption-side: bottom; background-color: var(--accent-color); padding: 0 defaults.$padding-4 defaults.$padding-4; text-align: center; border-bottom-left-radius: defaults.$border-radius; border-bottom-right-radius: defaults.$border-radius; } img { max-width: 100%; height: auto; } &:has(audio) { width: 100%; audio { width: 100%; } } } img { max-width: 100%; border-radius: defaults.$border-radius; } blockquote { margin: defaults.$padding-16 0; padding: defaults.$padding-8 defaults.$padding-16 defaults.$padding-8 (defaults.$padding-16 - defaults.$padding-4); //to keep total left space 16dp border: defaults.$border-1 solid var(--accent-color); border-left: defaults.$border-4 solid var(--accent-color); border-radius: defaults.$border-radius; } table:not(.lntable):not(.highlight) { display: table; border-spacing: 0; border-collapse: collapse; margin-top: defaults.$padding-16; margin-bottom: defaults.$padding-16; width: 100%; text-align: left; thead { border-bottom: defaults.$border-4 solid var(--accent-color); } tr th, tr td { padding: defaults.$padding-8 defaults.$padding-16; } tr { border-bottom: defaults.$border-2 solid var(--accent-color); } tr:nth-child(2n) { background: var(--accent-color-lite); } } hr { height: defaults.$border-2; border: none; background: var(--accent-color); } ul, ol { padding-left: defaults.$padding-32; } dl { dt { font-weight: bolder; margin-top: defaults.$padding-16; } dd { margin-left: defaults.$padding-32; } } code { padding: defaults.$padding-2 defaults.$padding-4; } pre, code { background-color: var(--code-background); border-radius: defaults.$border-radius; color: var(--code-font-color); font-size: defaults.$font-size-14; line-height: defaults.$padding-20; } pre code { display: block; padding: defaults.$padding-16; width: 100%; overflow: auto; max-height: var(--code-max-height); } mark { background-color: var(--mark-color); } &__align { text-align: left; &--left { h1, h2, h3, h4, h5, h6 { justify-content: flex-start; } } &--center { text-align: center; h1, h2, h3, h4, h5, h6 { justify-content: center; } } &--right { text-align: right; h1, h2, h3, h4, h5, h6 { justify-content: flex-end; } } } } ================================================ FILE: src/sass/_mobile.scss ================================================ @use "defaults"; @media screen and (max-width: defaults.$sm-breakpoint) { .gdoc-nav { margin-left: -(defaults.$menu-width); font-size: defaults.$font-size-base; &__control { display: inline-block; } } .gdoc-header { svg.gdoc-icon { width: defaults.$font-size-24; height: defaults.$font-size-24; } } .gdoc-brand { font-size: defaults.$font-size-24; line-height: defaults.$font-size-24; &__img { display: none; } } .gdoc-menu-header { &__items { display: none; } &__control { svg.gdoc-icon.gdoc_keyboard_arrow_right { display: none; } } &__control, &__home { display: flex; } } .gdoc-error { padding: defaults.$padding-96 defaults.$padding-16; svg.gdoc-icon { width: defaults.$font-size-96; height: defaults.$font-size-96; } &__message { padding-left: defaults.$padding-32; } &__line { padding: defaults.$padding-4 0; } &__title { font-size: defaults.$font-size-32; } } .gdoc-page__header .breadcrumb, .hidden-mobile { display: none; } .flex-mobile-column { flex-direction: column; &.gdoc-columns { margin: defaults.$padding-32 0; } .gdoc-columns__content { min-width: auto; margin: 0; } } .wrapper:has(#menu-control:checked) { .gdoc-nav nav, .gdoc-page { transform: translateX(defaults.$menu-width); } .gdoc-page { opacity: 0.25; } svg.gdoc-icon.gdoc_menu { display: none; } svg.gdoc-icon.gdoc_arrow_back { display: inline-block; } } .wrapper:has(#menu-header-control:checked) { .gdoc-brand { display: none; } .gdoc-menu-header { &__items { display: flex; } &__control { svg.gdoc-icon.gdoc_keyboard_arrow_left { display: none; } svg.gdoc-icon.gdoc_keyboard_arrow_right { display: inline-block; } } } } } ================================================ FILE: src/sass/_normalize.css ================================================ /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ /* Document ========================================================================== */ /** * 1. Correct the line height in all browsers. * 2. Prevent adjustments of font size after orientation changes in iOS. */ html { line-height: 1.15; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ } /* Sections ========================================================================== */ /** * Remove the margin in all browsers. */ body { margin: 0; } /** * Render the `main` element consistently in IE. */ main { display: block; } /** * Correct the font size and margin on `h1` elements within `section` and * `article` contexts in Chrome, Firefox, and Safari. */ h1 { font-size: 2em; margin: 0.67em 0; line-height: 1.2em; } /* Grouping content ========================================================================== */ /** * 1. Add the correct box sizing in Firefox. * 2. Show the overflow in Edge and IE. */ hr { box-sizing: content-box; /* 1 */ height: 0; /* 1 */ overflow: visible; /* 2 */ } /** * 1. Correct the inheritance and scaling of font size in all browsers. * 2. Correct the odd `em` font sizing in all browsers. */ pre { font-family: monospace, monospace; /* 1 */ font-size: 1em; /* 2 */ } /* Text-level semantics ========================================================================== */ /** * Remove the gray background on active links in IE 10. */ a { background-color: transparent; } /** * 1. Remove the bottom border in Chrome 57- * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. */ abbr[title] { border-bottom: none; /* 1 */ text-decoration: underline; /* 2 */ text-decoration: underline dotted; /* 2 */ } /** * Add the correct font weight in Chrome, Edge, and Safari. */ b, strong { font-weight: bolder; } /** * 1. Correct the inheritance and scaling of font size in all browsers. * 2. Correct the odd `em` font sizing in all browsers. */ code, kbd, samp { font-family: monospace, monospace; /* 1 */ font-size: 1em; /* 2 */ } /** * Add the correct font size in all browsers. */ small { font-size: 80%; } /** * Prevent `sub` and `sup` elements from affecting the line height in * all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } /* Embedded content ========================================================================== */ /** * Remove the border on images inside links in IE 10. */ img { border-style: none; } /* Forms ========================================================================== */ /** * 1. Change the font styles in all browsers. * 2. Remove the margin in Firefox and Safari. */ button, input, optgroup, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 1 */ line-height: 1.15; /* 1 */ margin: 0; /* 2 */ } /** * Show the overflow in IE. * 1. Show the overflow in Edge. */ button, input { /* 1 */ overflow: visible; } /** * Remove the inheritance of text transform in Edge, Firefox, and IE. * 1. Remove the inheritance of text transform in Firefox. */ button, select { /* 1 */ text-transform: none; } /** * Correct the inability to style clickable types in iOS and Safari. */ button, [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; } /** * Remove the inner border and padding in Firefox. */ button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { border-style: none; padding: 0; } /** * Restore the focus styles unset by the previous rule. */ button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { outline: 1px dotted ButtonText; } /** * Correct the padding in Firefox. */ fieldset { padding: 0.35em 0.75em 0.625em; } /** * 1. Correct the text wrapping in Edge and IE. * 2. Correct the color inheritance from `fieldset` elements in IE. * 3. Remove the padding so developers are not caught out when they zero out * `fieldset` elements in all browsers. */ legend { box-sizing: border-box; /* 1 */ color: inherit; /* 2 */ display: table; /* 1 */ max-width: 100%; /* 1 */ padding: 0; /* 3 */ white-space: normal; /* 1 */ } /** * Add the correct vertical alignment in Chrome, Firefox, and Opera. */ progress { vertical-align: baseline; } /** * Remove the default vertical scrollbar in IE 10+. */ textarea { overflow: auto; } /** * 1. Add the correct box sizing in IE 10. * 2. Remove the padding in IE 10. */ [type="checkbox"], [type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ } /** * Correct the cursor style of increment and decrement buttons in Chrome. */ [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; } /** * 1. Correct the odd appearance in Chrome and Safari. * 2. Correct the outline style in Safari. */ [type="search"] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } /** * Remove the inner padding in Chrome and Safari on macOS. */ [type="search"]::-webkit-search-decoration { -webkit-appearance: none; } /** * 1. Correct the inability to style clickable types in iOS and Safari. * 2. Change font properties to `inherit` in Safari. */ ::-webkit-file-upload-button { -webkit-appearance: button; /* 1 */ font: inherit; /* 2 */ } /* Interactive ========================================================================== */ /* * Add the correct display in Edge, IE 10+, and Firefox. */ details { display: block; } /* * Add the correct display in all browsers. */ summary { display: list-item; } /* Misc ========================================================================== */ /** * Add the correct display in IE 10+. */ template { display: none; } /** * Add the correct display in IE 10. */ [hidden] { display: none; } ================================================ FILE: src/sass/_print.scss ================================================ @use "defaults"; @media print { .gdoc-nav, .gdoc-footer .container span:not(:first-child), .gdoc-paging, .editpage { display: none; } .gdoc-footer { border-top: defaults.$border-1 solid defaults.$gray-300; } .gdoc-markdown pre { white-space: pre-wrap; overflow-wrap: break-word; } .chroma code { border: defaults.$border-1 solid defaults.$gray-300; padding: defaults.$padding-8 !important; font-weight: normal !important; } .gdoc-markdown code { font-weight: bold; } a, a:visited { color: inherit !important; text-decoration: none !important; } .gdoc-toc { flex: none; nav { position: relative; width: auto; } } .wrapper { display: block; main { display: block; } } } ================================================ FILE: src/sass/_shortcodes.scss ================================================ @use "sass:color"; @use "defaults"; // {{< expand "Label" "icon" >}} .gdoc-expand { margin: defaults.$padding-16 0; border: defaults.$border-1 solid var(--accent-color); border-radius: defaults.$border-radius; overflow: hidden; &__head { background: var(--accent-color-lite); padding: defaults.$padding-8 defaults.$padding-16; cursor: pointer; user-select: none; } &__content { display: none; padding: 0 defaults.$padding-16; } &__control:checked + &__content { display: block; } .gdoc-page__anchor { display: none; } } // {{< tabs >}} .gdoc-tabs { margin: defaults.$padding-16 0; border: defaults.$border-1 solid var(--accent-color); border-radius: defaults.$border-radius; overflow: hidden; display: flex; flex-wrap: wrap; &__label { display: inline-block; padding: defaults.$padding-8 defaults.$padding-16; border-bottom: defaults.$border-1 transparent; cursor: pointer; user-select: none; } &__content { order: 999; //Move content blocks to the end width: 100%; border-top: defaults.$border-1 solid var(--accent-color-lite); padding: 0 defaults.$padding-16; display: none; } &__control:checked + &__label { border-bottom: defaults.$border-2 solid var(--link-color); } &__control:checked + &__label + &__content { display: block; } .gdoc-page__anchor { display: none; } } // {{< columns >}} .gdoc-columns { margin: defaults.$padding-16 0; &--regular > :first-child { flex: 1; } &--small > :first-child { flex: 0.35; min-width: defaults.$body-min-width * 0.35; } &--large > :first-child { flex: 1.65; min-width: defaults.$body-min-width * 1.65; } &__content { flex: 1 1; min-width: defaults.$body-min-width * 0.66; padding: 0; } .gdoc-page__anchor { display: none; } } // {{< button >}} .gdoc-button { $root: &; margin: defaults.$padding-16 0; display: inline-block; background: var(--accent-color-lite); border: defaults.$border-1 solid var(--accent-color); border-radius: defaults.$border-radius; cursor: pointer; user-select: none; &__link { display: inline-block; color: inherit !important; text-decoration: none !important; } &:hover { background: var(--button-background); border-color: var(--button-border-color); color: defaults.$gray-100; } &--regular { font-size: defaults.$font-size-base; #{$root}__link { padding: defaults.$padding-4 defaults.$padding-8; } } &--large { font-size: defaults.$font-size-20; #{$root}__link { padding: defaults.$padding-8 defaults.$padding-16; } } } // {{< hint >}} .gdoc-hint { $root: &; @each $name, $color in defaults.$hint-colors { &.#{$name} { border-color: $color; padding: 0; #{$root}__title { background-color: color.adjust($color, $alpha: -0.9); border-start-start-radius: inherit; border-start-end-radius: inherit; position: relative; z-index: -10; outline: color.adjust($color, $alpha: -0.9); } } } &__title { padding: defaults.$padding-4 defaults.$padding-16; font-weight: bold; color: var(--body-font-color); margin-left: -5px; @each $name, $icon in defaults.$hint-icons { i.fa.#{$name} { width: defaults.$font-size-24; height: defaults.$font-size-24; mask-image: url(img/geekdoc-stack.svg##{$icon}); mask-repeat: no-repeat; mask-size: contain; background-color: var(--body-font-color); } } .gdoc-icon { width: defaults.$font-size-24; height: defaults.$font-size-24; } } &__text { padding: defaults.$padding-4 defaults.$padding-16; } .gdoc-page__anchor { display: none; } } // {{< mermaid >}} .gdoc-mermaid { font-family: var(--body-font-family); // Fix height of mermaid SVG elements (see https://github.com/mermaid-js/mermaid/issues/2481) > svg { height: 100%; padding: defaults.$padding-8; } } // {{< propertylist >}} .gdoc-props { &__title, &__default { padding: 0; margin: 0; font-family: var(--code-font-family); } &__meta { gap: 0.5em; line-height: normal; margin-bottom: defaults.$padding-4; &:hover .gdoc-page__anchor svg.gdoc-icon { color: var(--control-icons); } } @each $name, $color in defaults.$hint-colors { &__tag.#{$name} { border-color: color.scale($color, $lightness: 90%, $saturation: -30%); background-color: color.scale($color, $lightness: 95%, $saturation: -30%); } } &__tag { font-size: defaults.$font-size-14; font-weight: normal; background-color: defaults.$gray-100; border: defaults.$border-1 solid defaults.$gray-200; border-radius: defaults.$border-radius; padding: defaults.$padding-2 defaults.$padding-4; color: defaults.$body-font-color; } &__default { font-size: defaults.$font-size-14; } } // {{% progress %}} .gdoc-progress { margin-bottom: defaults.$padding-16; &__label { padding: defaults.$padding-4 0; &--name { font-weight: bold; } } &__wrap { background-color: var(--accent-color-lite); border-radius: 1em; box-shadow: inset 0 0 0 defaults.$border-1 var(--accent-color); } &__bar { height: 1em; border-radius: 1em; background-image: linear-gradient( -45deg, rgba(255, 255, 255, 0.125) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.125) 50%, rgba(255, 255, 255, 0.125) 75%, transparent 75%, transparent ); background-size: 2.5em 2.5em; background-color: defaults.$main-color; @each $name, $color in defaults.$hint-colors { &.#{$name} { background-image: linear-gradient( -45deg, #{color.scale($color, $lightness: -20%)} 25%, transparent 25%, transparent 50%, #{color.scale($color, $lightness: -20%)} 50%, #{color.scale($color, $lightness: -20%)} 75%, transparent 75%, transparent ); background-color: $color; } } } } ================================================ FILE: src/sass/_utils.scss ================================================ @use "defaults"; .flex { display: flex; } .flex-auto { flex: 1 1 auto; } .flex-25 { flex: 1 1 25%; } .flex-inline { display: inline-flex; } .flex-even { flex: 1 1; } .flex-wrap { flex-wrap: wrap; } .flex-grid { flex-direction: column; border: defaults.$border-1 solid var(--accent-color); border-radius: defaults.$border-radius; background: var(--accent-color-lite); } .gap-8 { flex-wrap: wrap; gap: defaults.$padding-8; } .gap-16 { flex-wrap: wrap; gap: defaults.$padding-16; } .justify-start { justify-content: flex-start; } .justify-end { justify-content: flex-end; } .justify-center { justify-content: center; } .justify-between { justify-content: space-between; } .align-center { align-items: center; } .mx-auto { margin: 0 auto; } .text-center { text-align: center; } .text-right { text-align: right; } .no-wrap { white-space: nowrap; } .hidden { display: none !important; } .svg-sprite { position: absolute; width: 0; height: 0; overflow: hidden; } .table-wrap { overflow: auto; margin: defaults.$padding-16 0; > table { margin: 0 !important; } } .badge-placeholder { display: inline-block; min-width: 4rem; } .w-full { width: 100%; } ================================================ FILE: src/sass/main.scss ================================================ @use "_normalize"; @use "_utils"; @use "_fonts"; @use "_base"; @use "_markdown"; @use "_asciidoc"; @use "_shortcodes"; ================================================ FILE: src/sass/mobile.scss ================================================ @use "sass:color"; @use "_defaults"; @use "_mobile"; ================================================ FILE: src/sass/print.scss ================================================ @use "sass:color"; @use "_defaults"; @use "_print"; ================================================ FILE: src/static/custom.css ================================================ /* You can add custom styles here. */ ================================================ FILE: svgsprite.config.json ================================================ { "shape": { "id": { "generator": "gdoc_%s" }, "dimension": { "maxWidth": 22, "maxHeight": 22, "attributes": false }, "spacing": { "padding": 5, "box": "content" }, "dest": "build/icons" }, "svg": { "xmlDeclaration": false, "rootAttributes": { "class": "svg-sprite" } }, "mode": { "defs": { "dest": "build/sprites/", "sprite": "geekdoc.svg", "bust": false }, "stack": { "dest": "build/img/", "sprite": "geekdoc-stack.svg", "bust": false } } } ================================================ FILE: theme.toml ================================================ name = "Geekdoc" license = "MIT" licenselink = "https://github.com/thegeeklab/hugo-geekdoc/blob/main/LICENSE" description = "Hugo theme made for documentation" homepage = "https://geekdocs.de/" demosite = "https://geekdocs.de/" tags = ["docs", "documentation", "responsive", "simple"] min_version = "0.156" [author] name = "Robert Kaussow" homepage = "https://thegeeklab.de/" ================================================ FILE: webpack.config.js ================================================ import path from "path" import { glob } from "glob" import { fileURLToPath } from "url" import { WebpackManifestPlugin } from "webpack-manifest-plugin" import FaviconsWebpackPlugin from "favicons-webpack-plugin" import RemoveEmptyScriptsPlugin from "webpack-remove-empty-scripts" import CopyPlugin from "copy-webpack-plugin" import { SRIPlugin, GitVersionPlugin } from "./webpack.plugins.js" const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const nodeModulesPath = path.resolve(__dirname, "node_modules") var config = { entry: { css: [ path.resolve("src", "sass", "main.scss"), path.resolve("src", "sass", "mobile.scss"), path.resolve("src", "sass", "print.scss") ], main: path.resolve("src", "js", "index.js"), colortheme: path.resolve("src", "js", "colorTheme.js"), mermaid: path.resolve("src", "js", "mermaid.js"), katex: [path.resolve("src", "js", "katex.js")].concat( glob.sync(path.join(nodeModulesPath, "katex", "dist", "fonts", "*.{woff,woff2}")) ), search: [path.resolve("src", "js", "search.js")] }, output: { filename: "js/[name]-[contenthash:8].bundle.min.js", chunkFilename: "js/[name]-[contenthash:8].chunk.min.js", path: path.join(__dirname, "static"), clean: true }, watchOptions: { ignored: ["/exampleSite/", "/node_modules/"] }, target: ["web", "es2017"], plugins: [ new CopyPlugin({ patterns: [ { from: "**/*", context: path.resolve(__dirname, "src", "static") }, { from: "fonts/*.{woff,woff2}", context: path.resolve(__dirname, "build") }, { from: "sprites/*.svg", to: path.resolve(__dirname, "assets"), context: path.resolve(__dirname, "build") }, { from: "img/*.svg", context: path.resolve(__dirname, "build") } ] }), new FaviconsWebpackPlugin({ logo: path.resolve("src", "static", "favicon", "favicon.svg"), prefix: "favicon/", inject: false, favicons: { background: "#efefef", theme_color: "#efefef", icons: { android: { offset: 10 }, appleIcon: { offset: 10 }, appleStartup: { offset: 10 }, favicons: true, windows: { offset: 10 }, yandex: false } } }), new RemoveEmptyScriptsPlugin(), new WebpackManifestPlugin({ fileName: "../data/assets.json", publicPath: "", writeToFileEmit: true, generate(seed, files) { let manifest = {} files.forEach(function (element) { if (element.name.endsWith("VERSION")) return if (element.name.endsWith(".svg")) return if (element.name.startsWith("fonts/")) return if (element.name.startsWith("/favicon")) return Object.assign(manifest, { [element.name]: { src: element.path } }) }) return manifest } }), new SRIPlugin({ sourceFile: "data/assets.json" }), new GitVersionPlugin({ outputFile: "../VERSION" }) ] } export default (env, argv) => { if (argv.mode === "development") { config.devtool = "source-map" } config.module = { rules: [ { test: /\.(woff|woff2|eot|ttf|otf)$/i, type: "asset/resource", generator: { filename: "fonts/[name][ext]" } }, { test: /\.(sa|sc|c)ss$/i, type: "asset/resource", generator: { filename: "[name]-[contenthash:8].min.css" }, use: [ { loader: "postcss-loader", options: { postcssOptions: { plugins: ["autoprefixer"] } } }, { loader: "sass-loader", options: { sourceMap: argv.mode === "development" ? true : false, sassOptions: { outputStyle: argv.mode === "development" ? "expanded" : "compressed" } } } ] } ] } return config } ================================================ FILE: webpack.plugins.js ================================================ import fs from "fs" import crypto from "crypto" import path from "path" import { validate } from "schema-utils" import { access as accessCps } from "fs" import { execFile as execFileCps } from "child_process" import { promisify } from "util" class SRIPlugin { static defaultOptions = { algorithm: "sha512", sourceFile: "assets.json" } constructor(options = {}) { this.options = { ...SRIPlugin.defaultOptions, ...options } validate( { type: "object", properties: { sourceFile: { type: "string" }, outputFile: { type: "string" }, algorithm: { type: "string" } } }, options, { name: "SRI Plugin", baseDataPath: "options" } ) } apply(compiler) { compiler.hooks.done.tap("SRIPlugin", () => { const data = JSON.parse(fs.readFileSync(this.options.sourceFile, "utf8")) const outputFile = this.options.outputFile || this.options.sourceFile const { algorithm } = this.options const calculateSRI = (file) => { const fileContent = fs.readFileSync(path.join(".", "static", file)) const hash = crypto.createHash(algorithm).update(fileContent).digest("base64") return `${algorithm}-${hash}` } Object.keys(data).forEach((key) => { data[key].integrity = calculateSRI(data[key].src) }) fs.writeFileSync(outputFile, JSON.stringify(data, null, 2), { encoding: "utf8", flag: "w" }) }) } } class GitVersionPlugin { static defaultOptions = { outputFile: "VERSION" } constructor(options = {}) { this.options = { ...GitVersionPlugin.defaultOptions, ...options } validate( { type: "object", properties: { outputFile: { type: "string" } } }, options, { baseDataPath: "options", name: "GitVersion Plugin" } ) } apply(compiler) { const { webpack, hooks, context } = compiler const { Compilation } = webpack hooks.beforeCompile.tapPromise("GitVersionPlugin", async () => { const access = promisify(accessCps) try { await access(".git") this.dependsOnGit = true } catch { this.dependsOnGit = false } }) hooks.compilation.tap("GitVersionPlugin", (compilation) => { if (this.dependsOnGit) { compilation.fileDependencies.add(path.join(context, ".git/logs/HEAD")) compilation.contextDependencies.add(path.join(context, ".git/refs/tags")) } compilation.hooks.processAssets.tapPromise( { name: "GitVersionPlugin", stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL }, async (assets) => { try { const v = await this.version() assets[this.options.outputFile] = { source: () => `${v}\n`, size: () => v.length + 1 } } catch { assets[this.options.outputFile] = { source: () => "", size: () => 0 } } } ) }) } async version() { const execFile = promisify(execFileCps) try { const { stdout: describe } = await execFile("git", ["describe", "--long", "--tags"]) const [, tag, offset] = describe.trim().match(/^(.*)-(\d+)-g[0-9a-f]+$/) return parseInt(offset) === 0 ? tag : this.getBranchAndHash() } catch { return this.getBranchAndHash() } } async getBranchAndHash() { const execFile = promisify(execFileCps) const [{ stdout: branch }, { stdout: hash }] = await Promise.all([ execFile("git", ["rev-parse", "--abbrev-ref", "HEAD"]), execFile("git", ["rev-parse", "HEAD"]) ]) return `${branch.trim()}@${hash.substring(0, 7)}` } } export { SRIPlugin, GitVersionPlugin }