mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-31 10:42:38 +00:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f1e799c2e1 | |||
| b289b17c43 | |||
| 85c1727748 | |||
| 641403f7de | |||
| 24cc25552f | |||
| a2ca95629a | |||
| 367fe526e2 | |||
| 5de3913ed4 | |||
| 7b7a0f3624 | |||
| cb7a4339b7 | |||
| 157d3703c3 | |||
| 9c2f8ec61b | |||
| bd77944ba2 | |||
| c1f4228d61 | |||
| 503dcf6252 | |||
| 5dd0ba00f7 | |||
| 2e835d0841 | |||
| 2c77719cd6 | |||
| d89b9d891c | |||
| 8721a35202 | |||
| fd38aee694 | |||
| d25f7ec172 | |||
| 304a7e5e74 | |||
| a024bc7d76 | |||
| c054e18827 | |||
| 34dcac53bf | |||
| ee438606dd | |||
| fd8b0fbf8a | |||
| 9b5f786df8 | |||
| e6feb9e0be | |||
| 5e4ffa0e89 | |||
| 0cdcc2b584 | |||
| a591c4406a | |||
| 2d86a0512c | |||
| f02da7fbce | |||
| 22ee0918f3 | |||
| b50ab04031 | |||
| b772f0e3d2 | |||
| d58c0198d3 | |||
| c2fb221209 | |||
| 4245a4514d | |||
| f0c1852978 | |||
| a352e69b02 | |||
| 1dd27be81a | |||
| eb7a5aabaa | |||
| 029d1e0ced | |||
| e865d59844 | |||
| 377287a614 | |||
| 0270364a34 | |||
| 760c13a7ac | |||
| 3bd73d262d | |||
| 7104de83ce | |||
| 835579b338 | |||
| 05e067ced8 | |||
| ee48d9692a | |||
| db28695ff5 | |||
| 778f0d9002 | |||
| 13b208e2f7 | |||
| 329b2342f0 | |||
| 33b46d8a41 | |||
| 6c68142cc1 |
@@ -4,7 +4,7 @@ parameters:
|
||||
defaults: &defaults
|
||||
resource_class: large
|
||||
docker:
|
||||
- image: bepsays/ci-hugoreleaser:1.22301.20401
|
||||
- image: bepsays/ci-hugoreleaser:1.22400.20000
|
||||
environment: &buildenv
|
||||
GOMODCACHE: /root/project/gomodcache
|
||||
version: 2
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
environment:
|
||||
<<: [*buildenv]
|
||||
docker:
|
||||
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22301.20401
|
||||
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22400.20000
|
||||
steps:
|
||||
- *restore-cache
|
||||
- &attach-workspace
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.22.x, 1.23.x]
|
||||
go-version: [1.23.x, 1.24.x]
|
||||
os: [ubuntu-latest, windows-latest] # macos disabled for now because of disk space issues.
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
|
||||
@@ -93,6 +93,7 @@ Most title/subjects should have a lower-cased prefix with a colon and one whites
|
||||
* If this commit touches many packages without a common functional topic, prefix with `all:` (e.g. `all: Reformat Go code`)
|
||||
* If this is a documentation update, prefix with `docs:`.
|
||||
* If nothing of the above applies, just leave the prefix out.
|
||||
* Note that the above excludes nouns seen in other repositories, e.g. "chore:".
|
||||
|
||||
Also, if your commit references one or more GitHub issues, always end your commit message body with *See #1234* or *Fixes #1234*.
|
||||
Replace *1234* with the GitHub issue ID. The last example will close the issue when the commit is merged into *master*.
|
||||
|
||||
@@ -34,6 +34,7 @@ A fast and flexible static site generator built with love by [bep], [spf13], and
|
||||
[](https://goreportcard.com/report/github.com/gohugoio/hugo)
|
||||
|
||||
[Website] | [Installation] | [Documentation] | [Support] | [Contributing] | <a rel="me" href="https://fosstodon.org/@gohugoio">Mastodon</a>
|
||||
|
||||
## Overview
|
||||
|
||||
Hugo is a [static site generator] written in [Go], optimized for speed and designed for flexibility. With its advanced templating system and fast asset pipelines, Hugo renders a complete site in seconds, often less.
|
||||
@@ -69,6 +70,23 @@ See the [features] section of the documentation for a comprehensive summary of H
|
||||
<a href="https://www.jetbrains.com/go/?utm_source=OSS&utm_medium=referral&utm_campaign=hugo" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/assets/images/sponsors/goland.svg" width="200" alt="The complete IDE crafted for professional Go developers."></a>
|
||||
</p>
|
||||
|
||||
## Editions
|
||||
|
||||
Hugo is available in three editions: standard, extended, and extended/deploy. While the standard edition provides core functionality, the extended and extended/deploy editions offer advanced features.
|
||||
|
||||
Feature|extended edition|extended/deploy edition
|
||||
:--|:-:|:-:
|
||||
Encode to the WebP format when [processing images]. You can decode WebP images with any edition.|:heavy_check_mark:|:heavy_check_mark:
|
||||
[Transpile Sass to CSS] using the embedded LibSass transpiler. You can use the [Dart Sass] transpiler with any edition.|:heavy_check_mark:|:heavy_check_mark:
|
||||
Deploy your site directly to a Google Cloud Storage bucket, an AWS S3 bucket, or an Azure Storage container. See [details].|:x:|:heavy_check_mark:
|
||||
|
||||
[dart sass]: /functions/css/sass/#dart-sass
|
||||
[processing images]: /content-management/image-processing/
|
||||
[transpile sass to css]: /functions/css/sass/
|
||||
[details]: /hosting-and-deployment/hugo-deploy/
|
||||
|
||||
Unless your specific deployment needs require the extended/deploy edition, we recommend the extended edition.
|
||||
|
||||
## Installation
|
||||
|
||||
Install Hugo from a [prebuilt binary], package manager, or package repository. Please see the installation instructions for your operating system:
|
||||
@@ -80,15 +98,11 @@ Install Hugo from a [prebuilt binary], package manager, or package repository. P
|
||||
|
||||
## Build from source
|
||||
|
||||
Hugo is available in two editions: standard and extended. With the extended edition you can:
|
||||
|
||||
- Encode to the WebP format when processing images. You can decode WebP images with either edition.
|
||||
- Transpile Sass to CSS using the embedded LibSass transpiler. The extended edition is not required to use the Dart Sass transpiler.
|
||||
|
||||
Prerequisites to build Hugo from source:
|
||||
|
||||
- Standard edition: Go 1.20 or later
|
||||
- Extended edition: Go 1.20 or later, and GCC
|
||||
- Standard edition: Go 1.23.0 or later
|
||||
- Extended edition: Go 1.23.0 or later, and GCC
|
||||
- Extended/deploy edition: Go 1.23.0 or later, and GCC
|
||||
|
||||
Build the standard edition:
|
||||
|
||||
@@ -102,6 +116,12 @@ Build the extended edition:
|
||||
CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@latest
|
||||
```
|
||||
|
||||
Build the extended/deploy edition:
|
||||
|
||||
```text
|
||||
CGO_ENABLED=1 go install -tags extended,withdeploy github.com/gohugoio/hugo@latest
|
||||
```
|
||||
|
||||
## Star History
|
||||
|
||||
[](https://star-history.com/#gohugoio/hugo&Timeline)
|
||||
@@ -149,7 +169,9 @@ Hugo stands on the shoulders of great open source libraries. Run `hugo env --log
|
||||
|
||||
```text
|
||||
github.com/BurntSushi/locker="v0.0.0-20171006230638-a6e239ea1c69"
|
||||
github.com/alecthomas/chroma/v2="v2.14.0"
|
||||
github.com/PuerkitoBio/goquery="v1.10.1"
|
||||
github.com/alecthomas/chroma/v2="v2.15.0"
|
||||
github.com/andybalholm/cascadia="v1.3.3"
|
||||
github.com/armon/go-radix="v1.0.1-0.20221118154546-54df44f2176c"
|
||||
github.com/bep/clocks="v0.5.0"
|
||||
github.com/bep/debounce="v1.2.0"
|
||||
@@ -158,73 +180,78 @@ github.com/bep/goat="v0.5.0"
|
||||
github.com/bep/godartsass/v2="v2.3.2"
|
||||
github.com/bep/golibsass="v1.2.0"
|
||||
github.com/bep/gowebp="v0.3.0"
|
||||
github.com/bep/imagemeta="v0.8.3"
|
||||
github.com/bep/imagemeta="v0.8.4"
|
||||
github.com/bep/lazycache="v0.7.0"
|
||||
github.com/bep/logg="v0.4.0"
|
||||
github.com/bep/mclib="v1.20400.20402"
|
||||
github.com/bep/overlayfs="v0.9.2"
|
||||
github.com/bep/simplecobra="v0.4.0"
|
||||
github.com/bep/simplecobra="v0.5.0"
|
||||
github.com/bep/tmc="v0.5.1"
|
||||
github.com/cespare/xxhash/v2="v2.3.0"
|
||||
github.com/clbanning/mxj/v2="v2.7.0"
|
||||
github.com/cli/safeexec="v1.0.1"
|
||||
github.com/cpuguy83/go-md2man/v2="v2.0.4"
|
||||
github.com/disintegration/gift="v1.2.1"
|
||||
github.com/dlclark/regexp2="v1.11.0"
|
||||
github.com/evanw/esbuild="v0.24.0"
|
||||
github.com/dlclark/regexp2="v1.11.5"
|
||||
github.com/dop251/goja="v0.0.0-20250125213203-5ef83b82af17"
|
||||
github.com/evanw/esbuild="v0.24.2"
|
||||
github.com/fatih/color="v1.18.0"
|
||||
github.com/frankban/quicktest="v1.14.6"
|
||||
github.com/fsnotify/fsnotify="v1.8.0"
|
||||
github.com/getkin/kin-openapi="v0.123.0"
|
||||
github.com/getkin/kin-openapi="v0.129.0"
|
||||
github.com/ghodss/yaml="v1.0.0"
|
||||
github.com/go-openapi/jsonpointer="v0.20.2"
|
||||
github.com/go-openapi/swag="v0.22.8"
|
||||
github.com/go-openapi/jsonpointer="v0.21.0"
|
||||
github.com/go-openapi/swag="v0.23.0"
|
||||
github.com/go-sourcemap/sourcemap="v2.1.4+incompatible"
|
||||
github.com/gobuffalo/flect="v1.0.3"
|
||||
github.com/gobwas/glob="v0.2.3"
|
||||
github.com/gohugoio/go-i18n/v2="v2.1.3-0.20230805085216-e63c13218d0e"
|
||||
github.com/gohugoio/hashstructure="v0.1.0"
|
||||
github.com/gohugoio/hashstructure="v0.5.0"
|
||||
github.com/gohugoio/httpcache="v0.7.0"
|
||||
github.com/gohugoio/hugo-goldmark-extensions/extras="v0.2.0"
|
||||
github.com/gohugoio/hugo-goldmark-extensions/passthrough="v0.3.0"
|
||||
github.com/gohugoio/locales="v0.14.0"
|
||||
github.com/gohugoio/localescompressed="v1.0.1"
|
||||
github.com/golang/freetype="v0.0.0-20170609003504-e2365dfdc4a0"
|
||||
github.com/google/go-cmp="v0.6.0"
|
||||
github.com/google/pprof="v0.0.0-20250208200701-d0013a598941"
|
||||
github.com/gorilla/websocket="v1.5.3"
|
||||
github.com/hairyhenderson/go-codeowners="v0.7.0"
|
||||
github.com/hashicorp/golang-lru/v2="v2.0.7"
|
||||
github.com/invopop/yaml="v0.2.0"
|
||||
github.com/jdkato/prose="v1.2.1"
|
||||
github.com/josharian/intern="v1.0.0"
|
||||
github.com/kr/pretty="v0.3.1"
|
||||
github.com/kr/text="v0.2.0"
|
||||
github.com/kyokomi/emoji/v2="v2.2.13"
|
||||
github.com/lucasb-eyer/go-colorful="v1.2.0"
|
||||
github.com/mailru/easyjson="v0.7.7"
|
||||
github.com/makeworld-the-better-one/dither/v2="v2.4.0"
|
||||
github.com/marekm4/color-extractor="v1.2.1"
|
||||
github.com/mattn/go-colorable="v0.1.13"
|
||||
github.com/mattn/go-isatty="v0.0.20"
|
||||
github.com/mattn/go-runewidth="v0.0.9"
|
||||
github.com/mazznoer/csscolorparser="v0.1.5"
|
||||
github.com/mitchellh/mapstructure="v1.5.1-0.20231216201459-8508981c8b6c"
|
||||
github.com/mohae/deepcopy="v0.0.0-20170929034955-c48cc78d4826"
|
||||
github.com/muesli/smartcrop="v0.3.0"
|
||||
github.com/niklasfasching/go-org="v1.7.0"
|
||||
github.com/oasdiff/yaml3="v0.0.0-20241210130736-a94c01f36349"
|
||||
github.com/oasdiff/yaml="v0.0.0-20241210131133-6b86fb107d80"
|
||||
github.com/olekukonko/tablewriter="v0.0.5"
|
||||
github.com/pbnjay/memory="v0.0.0-20210728143218-7b4eea64cf58"
|
||||
github.com/pelletier/go-toml/v2="v2.2.3"
|
||||
github.com/perimeterx/marshmallow="v1.1.5"
|
||||
github.com/pkg/browser="v0.0.0-20240102092130-5ac0b6a4141c"
|
||||
github.com/pkg/errors="v0.9.1"
|
||||
github.com/rivo/uniseg="v0.4.7"
|
||||
github.com/rogpeppe/go-internal="v1.13.1"
|
||||
github.com/russross/blackfriday/v2="v2.1.0"
|
||||
github.com/sass/dart-sass/compiler="1.81.0"
|
||||
github.com/sass/dart-sass/implementation="1.81.0"
|
||||
github.com/sass/dart-sass/protocol="3.1.0"
|
||||
github.com/sass/libsass="3.6.6"
|
||||
github.com/spf13/afero="v1.11.0"
|
||||
github.com/spf13/cast="v1.7.1"
|
||||
github.com/spf13/cobra="v1.8.1"
|
||||
github.com/spf13/fsync="v0.10.1"
|
||||
github.com/spf13/pflag="v1.0.5"
|
||||
github.com/spf13/pflag="v1.0.6"
|
||||
github.com/tdewolff/minify/v2="v2.20.37"
|
||||
github.com/tdewolff/parse/v2="v2.7.15"
|
||||
github.com/tetratelabs/wazero="v1.8.2"
|
||||
@@ -232,18 +259,22 @@ github.com/webmproject/libwebp="v1.3.2"
|
||||
github.com/yuin/goldmark-emoji="v1.0.4"
|
||||
github.com/yuin/goldmark="v1.7.8"
|
||||
go.uber.org/automaxprocs="v1.5.3"
|
||||
golang.org/x/crypto="v0.31.0"
|
||||
golang.org/x/exp="v0.0.0-20221031165847-c99f073a8326"
|
||||
golang.org/x/image="v0.22.0"
|
||||
golang.org/x/mod="v0.22.0"
|
||||
golang.org/x/net="v0.33.0"
|
||||
golang.org/x/sync="v0.10.0"
|
||||
golang.org/x/sys="v0.28.0"
|
||||
golang.org/x/text="v0.21.0"
|
||||
golang.org/x/tools="v0.28.0"
|
||||
google.golang.org/protobuf="v1.35.2"
|
||||
golang.org/x/crypto="v0.33.0"
|
||||
golang.org/x/exp="v0.0.0-20250210185358-939b2ce775ac"
|
||||
golang.org/x/image="v0.24.0"
|
||||
golang.org/x/mod="v0.23.0"
|
||||
golang.org/x/net="v0.35.0"
|
||||
golang.org/x/sync="v0.11.0"
|
||||
golang.org/x/sys="v0.30.0"
|
||||
golang.org/x/text="v0.22.0"
|
||||
golang.org/x/tools="v0.30.0"
|
||||
golang.org/x/xerrors="v0.0.0-20240903120638-7835f813f4da"
|
||||
gonum.org/v1/plot="v0.15.0"
|
||||
google.golang.org/protobuf="v1.36.5"
|
||||
gopkg.in/yaml.v2="v2.4.0"
|
||||
gopkg.in/yaml.v3="v3.0.1"
|
||||
oss.terrastruct.com/d2="v0.6.9"
|
||||
oss.terrastruct.com/util-go="v0.0.0-20241005222610-44c011a04896"
|
||||
rsc.io/qr="v0.2.0"
|
||||
software.sslmate.com/src/go-pkcs12="v0.2.0"
|
||||
```
|
||||
|
||||
Vendored
+11
-5
@@ -176,11 +176,12 @@ func (c *Cache) ClearMatching(predicatePartition func(k string, p PartitionManag
|
||||
}
|
||||
|
||||
// ClearOnRebuild prepares the cache for a new rebuild taking the given changeset into account.
|
||||
func (c *Cache) ClearOnRebuild(changeset ...identity.Identity) {
|
||||
// predicate is optional and will clear any entry for which it returns true.
|
||||
func (c *Cache) ClearOnRebuild(predicate func(k, v any) bool, changeset ...identity.Identity) {
|
||||
g := rungroup.Run[PartitionManager](context.Background(), rungroup.Config[PartitionManager]{
|
||||
NumWorkers: len(c.partitions),
|
||||
Handle: func(ctx context.Context, partition PartitionManager) error {
|
||||
partition.clearOnRebuild(changeset...)
|
||||
partition.clearOnRebuild(predicate, changeset...)
|
||||
return nil
|
||||
},
|
||||
})
|
||||
@@ -479,7 +480,12 @@ func (p *Partition[K, V]) clearMatching(predicate func(k, v any) bool) {
|
||||
})
|
||||
}
|
||||
|
||||
func (p *Partition[K, V]) clearOnRebuild(changeset ...identity.Identity) {
|
||||
func (p *Partition[K, V]) clearOnRebuild(predicate func(k, v any) bool, changeset ...identity.Identity) {
|
||||
if predicate == nil {
|
||||
predicate = func(k, v any) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
opts := p.getOptions()
|
||||
if opts.ClearWhen == ClearNever {
|
||||
return
|
||||
@@ -525,7 +531,7 @@ func (p *Partition[K, V]) clearOnRebuild(changeset ...identity.Identity) {
|
||||
// Second pass needs to be done in a separate loop to catch any
|
||||
// elements marked as stale in the other partitions.
|
||||
p.c.DeleteFunc(func(key K, v V) bool {
|
||||
if shouldDelete(key, v) {
|
||||
if predicate(key, v) || shouldDelete(key, v) {
|
||||
p.trace.Log(
|
||||
logg.StringFunc(
|
||||
func() string {
|
||||
@@ -601,7 +607,7 @@ type PartitionManager interface {
|
||||
adjustMaxSize(addend int) int
|
||||
getMaxSize() int
|
||||
getOptions() OptionsPartition
|
||||
clearOnRebuild(changeset ...identity.Identity)
|
||||
clearOnRebuild(predicate func(k, v any) bool, changeset ...identity.Identity)
|
||||
clearMatching(predicate func(k, v any) bool)
|
||||
clearStale()
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -147,13 +147,13 @@ func TestClear(t *testing.T) {
|
||||
|
||||
c.Assert(cache.Keys(predicateAll), qt.HasLen, 4)
|
||||
|
||||
cache.ClearOnRebuild()
|
||||
cache.ClearOnRebuild(nil)
|
||||
|
||||
// Stale items are always cleared.
|
||||
c.Assert(cache.Keys(predicateAll), qt.HasLen, 2)
|
||||
|
||||
cache = newTestCache(t)
|
||||
cache.ClearOnRebuild(identity.StringIdentity("changed"))
|
||||
cache.ClearOnRebuild(nil, identity.StringIdentity("changed"))
|
||||
|
||||
c.Assert(cache.Keys(nil), qt.HasLen, 1)
|
||||
|
||||
|
||||
@@ -448,7 +448,7 @@ func (r *rootCommand) PreRun(cd, runner *simplecobra.Commandeer) error {
|
||||
return err
|
||||
}
|
||||
// Set up the global logger early to allow info deprecations during config load.
|
||||
loggers.InitGlobalLogger(r.logger.Level(), false)
|
||||
loggers.SetGlobalLogger(r.logger)
|
||||
|
||||
r.changesFromBuild = make(chan []identity.Identity, 10)
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build withdeploy
|
||||
// +build withdeploy
|
||||
|
||||
package commands
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !withdeploy
|
||||
// +build !withdeploy
|
||||
|
||||
// Copyright 2024 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
|
||||
+7
-2
@@ -21,6 +21,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/chroma/v2"
|
||||
@@ -60,6 +61,10 @@ func newGenCommand() *genCommand {
|
||||
See https://xyproto.github.io/splash/docs/all.html for a preview of the available styles`,
|
||||
|
||||
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
||||
style = strings.ToLower(style)
|
||||
if !slices.Contains(styles.Names(), style) {
|
||||
return fmt.Errorf("invalid style: %s", style)
|
||||
}
|
||||
builder := styles.Get(style).Builder()
|
||||
if highlightStyle != "" {
|
||||
builder.Add(chroma.LineHighlight, highlightStyle)
|
||||
@@ -144,7 +149,7 @@ url: %s
|
||||
|
||||
return &simpleCommand{
|
||||
name: "doc",
|
||||
short: "Generate Markdown documentation for the Hugo CLI.",
|
||||
short: "Generate Markdown documentation for the Hugo CLI",
|
||||
long: `Generate Markdown documentation for the Hugo CLI.
|
||||
This command is, mostly, used to create up-to-date documentation
|
||||
of Hugo's command-line interface for https://gohugo.io/.
|
||||
@@ -196,7 +201,7 @@ url: %s
|
||||
newDocsHelper := func() simplecobra.Commander {
|
||||
return &simpleCommand{
|
||||
name: "docshelper",
|
||||
short: "Generate some data files for the Hugo docs.",
|
||||
short: "Generate some data files for the Hugo docs",
|
||||
|
||||
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
||||
r.Println("Generate docs data to", docsHelperTarget)
|
||||
|
||||
+14
-16
@@ -663,7 +663,20 @@ func (c *hugoBuilder) handleEvents(watcher *watcher.Batcher,
|
||||
var n int
|
||||
for _, ev := range evs {
|
||||
keep := true
|
||||
if ev.Has(fsnotify.Create) || ev.Has(fsnotify.Write) {
|
||||
// Write and rename operations are often followed by CHMOD.
|
||||
// There may be valid use cases for rebuilding the site on CHMOD,
|
||||
// but that will require more complex logic than this simple conditional.
|
||||
// On OS X this seems to be related to Spotlight, see:
|
||||
// https://github.com/go-fsnotify/fsnotify/issues/15
|
||||
// A workaround is to put your site(s) on the Spotlight exception list,
|
||||
// but that may be a little mysterious for most end users.
|
||||
// So, for now, we skip reload on CHMOD.
|
||||
// We do have to check for WRITE though. On slower laptops a Chmod
|
||||
// could be aggregated with other important events, and we still want
|
||||
// to rebuild on those
|
||||
if ev.Op == fsnotify.Chmod {
|
||||
keep = false
|
||||
} else if ev.Has(fsnotify.Create) || ev.Has(fsnotify.Write) {
|
||||
if _, err := os.Stat(ev.Name); err != nil {
|
||||
keep = false
|
||||
}
|
||||
@@ -805,21 +818,6 @@ func (c *hugoBuilder) handleEvents(watcher *watcher.Batcher,
|
||||
continue
|
||||
}
|
||||
|
||||
// Write and rename operations are often followed by CHMOD.
|
||||
// There may be valid use cases for rebuilding the site on CHMOD,
|
||||
// but that will require more complex logic than this simple conditional.
|
||||
// On OS X this seems to be related to Spotlight, see:
|
||||
// https://github.com/go-fsnotify/fsnotify/issues/15
|
||||
// A workaround is to put your site(s) on the Spotlight exception list,
|
||||
// but that may be a little mysterious for most end users.
|
||||
// So, for now, we skip reload on CHMOD.
|
||||
// We do have to check for WRITE though. On slower laptops a Chmod
|
||||
// could be aggregated with other important events, and we still want
|
||||
// to rebuild on those
|
||||
if ev.Op&(fsnotify.Chmod|fsnotify.Write|fsnotify.Create) == fsnotify.Chmod {
|
||||
continue
|
||||
}
|
||||
|
||||
walkAdder := func(path string, f hugofs.FileMetaInfo) error {
|
||||
if f.IsDir() {
|
||||
c.r.logger.Println("adding created directory to watchlist", path)
|
||||
|
||||
+14
-14
@@ -44,16 +44,16 @@ func newModCommands() *modCommands {
|
||||
|
||||
npmCommand := &simpleCommand{
|
||||
name: "npm",
|
||||
short: "Various npm helpers.",
|
||||
short: "Various npm helpers",
|
||||
long: `Various npm (Node package manager) helpers.`,
|
||||
commands: []simplecobra.Commander{
|
||||
&simpleCommand{
|
||||
name: "pack",
|
||||
short: "Experimental: Prepares and writes a composite package.json file for your project.",
|
||||
short: "Experimental: Prepares and writes a composite package.json file for your project",
|
||||
long: `Prepares and writes a composite package.json file for your project.
|
||||
|
||||
On first run it creates a "package.hugo.json" in the project root if not already there. This file will be used as a template file
|
||||
with the base dependency set.
|
||||
with the base dependency set.
|
||||
|
||||
This set will be merged with all "package.hugo.json" files found in the dependency tree, picking the version closest to the project.
|
||||
|
||||
@@ -80,12 +80,12 @@ so this may/will change in future versions of Hugo.
|
||||
commands: []simplecobra.Commander{
|
||||
&simpleCommand{
|
||||
name: "init",
|
||||
short: "Initialize this project as a Hugo Module.",
|
||||
short: "Initialize this project as a Hugo Module",
|
||||
long: `Initialize this project as a Hugo Module.
|
||||
It will try to guess the module path, but you may help by passing it as an argument, e.g:
|
||||
|
||||
|
||||
hugo mod init github.com/gohugoio/testshortcodes
|
||||
|
||||
|
||||
Note that Hugo Modules supports multi-module projects, so you can initialize a Hugo Module
|
||||
inside a subfolder on GitHub, as one example.
|
||||
`,
|
||||
@@ -111,7 +111,7 @@ so this may/will change in future versions of Hugo.
|
||||
},
|
||||
&simpleCommand{
|
||||
name: "verify",
|
||||
short: "Verify dependencies.",
|
||||
short: "Verify dependencies",
|
||||
long: `Verify checks that the dependencies of the current module, which are stored in a local downloaded source cache, have not been modified since being downloaded.`,
|
||||
withc: func(cmd *cobra.Command, r *rootCommand) {
|
||||
cmd.ValidArgsFunction = cobra.NoFileCompletions
|
||||
@@ -129,7 +129,7 @@ so this may/will change in future versions of Hugo.
|
||||
},
|
||||
&simpleCommand{
|
||||
name: "graph",
|
||||
short: "Print a module dependency graph.",
|
||||
short: "Print a module dependency graph",
|
||||
long: `Print a module dependency graph with information about module status (disabled, vendored).
|
||||
Note that for vendored modules, that is the version listed and not the one from go.mod.
|
||||
`,
|
||||
@@ -149,7 +149,7 @@ Note that for vendored modules, that is the version listed and not the one from
|
||||
},
|
||||
&simpleCommand{
|
||||
name: "clean",
|
||||
short: "Delete the Hugo Module cache for the current project.",
|
||||
short: "Delete the Hugo Module cache for the current project",
|
||||
long: `Delete the Hugo Module cache for the current project.`,
|
||||
withc: func(cmd *cobra.Command, r *rootCommand) {
|
||||
cmd.ValidArgsFunction = cobra.NoFileCompletions
|
||||
@@ -175,7 +175,7 @@ Note that for vendored modules, that is the version listed and not the one from
|
||||
},
|
||||
&simpleCommand{
|
||||
name: "tidy",
|
||||
short: "Remove unused entries in go.mod and go.sum.",
|
||||
short: "Remove unused entries in go.mod and go.sum",
|
||||
withc: func(cmd *cobra.Command, r *rootCommand) {
|
||||
cmd.ValidArgsFunction = cobra.NoFileCompletions
|
||||
applyLocalFlagsBuildConfig(cmd, r)
|
||||
@@ -190,7 +190,7 @@ Note that for vendored modules, that is the version listed and not the one from
|
||||
},
|
||||
&simpleCommand{
|
||||
name: "vendor",
|
||||
short: "Vendor all module dependencies into the _vendor directory.",
|
||||
short: "Vendor all module dependencies into the _vendor directory",
|
||||
long: `Vendor all module dependencies into the _vendor directory.
|
||||
If a module is vendored, that is where Hugo will look for it's dependencies.
|
||||
`,
|
||||
@@ -209,16 +209,16 @@ Note that for vendored modules, that is the version listed and not the one from
|
||||
|
||||
&simpleCommand{
|
||||
name: "get",
|
||||
short: "Resolves dependencies in your current Hugo Project.",
|
||||
short: "Resolves dependencies in your current Hugo project",
|
||||
long: `
|
||||
Resolves dependencies in your current Hugo Project.
|
||||
Resolves dependencies in your current Hugo project.
|
||||
|
||||
Some examples:
|
||||
|
||||
Install the latest version possible for a given module:
|
||||
|
||||
hugo mod get github.com/gohugoio/testshortcodes
|
||||
|
||||
|
||||
Install a specific version:
|
||||
|
||||
hugo mod get github.com/gohugoio/testshortcodes@v0.3.0
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ func newReleaseCommand() simplecobra.Commander {
|
||||
|
||||
return &simpleCommand{
|
||||
name: "release",
|
||||
short: "Release a new version of Hugo.",
|
||||
short: "Release a new version of Hugo",
|
||||
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
||||
rel, err := releaser.New(skipPush, try, step)
|
||||
if err != nil {
|
||||
|
||||
+75
-52
@@ -84,6 +84,10 @@ const (
|
||||
configChangeGoWork = "go work file"
|
||||
)
|
||||
|
||||
const (
|
||||
hugoHeaderRedirect = "X-Hugo-Redirect"
|
||||
)
|
||||
|
||||
func newHugoBuilder(r *rootCommand, s *serverCommand, onConfigLoaded ...func(reloaded bool) error) *hugoBuilder {
|
||||
var visitedURLs *types.EvictingQueue[string]
|
||||
if s != nil && !s.disableFastRender {
|
||||
@@ -115,7 +119,7 @@ func newServerCommand() *serverCommand {
|
||||
commands: []simplecobra.Commander{
|
||||
&simpleCommand{
|
||||
name: "trust",
|
||||
short: "Install the local CA in the system trust store.",
|
||||
short: "Install the local CA in the system trust store",
|
||||
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
||||
action := "-install"
|
||||
if uninstall {
|
||||
@@ -307,67 +311,65 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, net.Listener, string
|
||||
w.Header().Set(header.Key, header.Value)
|
||||
}
|
||||
|
||||
if redirect := serverConfig.MatchRedirect(requestURI); !redirect.IsZero() {
|
||||
// fullName := filepath.Join(dir, filepath.FromSlash(path.Clean("/"+name)))
|
||||
doRedirect := true
|
||||
// This matches Netlify's behavior and is needed for SPA behavior.
|
||||
// See https://docs.netlify.com/routing/redirects/rewrites-proxies/
|
||||
if !redirect.Force {
|
||||
path := filepath.Clean(strings.TrimPrefix(requestURI, baseURL.Path()))
|
||||
if root != "" {
|
||||
path = filepath.Join(root, path)
|
||||
}
|
||||
var fs afero.Fs
|
||||
f.c.withConf(func(conf *commonConfig) {
|
||||
fs = conf.fs.PublishDirServer
|
||||
})
|
||||
|
||||
fi, err := fs.Stat(path)
|
||||
|
||||
if err == nil {
|
||||
if fi.IsDir() {
|
||||
// There will be overlapping directories, so we
|
||||
// need to check for a file.
|
||||
_, err = fs.Stat(filepath.Join(path, "index.html"))
|
||||
doRedirect = err != nil
|
||||
} else {
|
||||
doRedirect = false
|
||||
if canRedirect(requestURI, r) {
|
||||
if redirect := serverConfig.MatchRedirect(requestURI, r.Header); !redirect.IsZero() {
|
||||
doRedirect := true
|
||||
// This matches Netlify's behavior and is needed for SPA behavior.
|
||||
// See https://docs.netlify.com/routing/redirects/rewrites-proxies/
|
||||
if !redirect.Force {
|
||||
path := filepath.Clean(strings.TrimPrefix(requestURI, baseURL.Path()))
|
||||
if root != "" {
|
||||
path = filepath.Join(root, path)
|
||||
}
|
||||
}
|
||||
}
|
||||
var fs afero.Fs
|
||||
f.c.withConf(func(conf *commonConfig) {
|
||||
fs = conf.fs.PublishDirServer
|
||||
})
|
||||
|
||||
fi, err := fs.Stat(path)
|
||||
|
||||
if doRedirect {
|
||||
switch redirect.Status {
|
||||
case 404:
|
||||
w.WriteHeader(404)
|
||||
file, err := fs.Open(strings.TrimPrefix(redirect.To, baseURL.Path()))
|
||||
if err == nil {
|
||||
defer file.Close()
|
||||
io.Copy(w, file)
|
||||
} else {
|
||||
fmt.Fprintln(w, "<h1>Page Not Found</h1>")
|
||||
if fi.IsDir() {
|
||||
// There will be overlapping directories, so we
|
||||
// need to check for a file.
|
||||
_, err = fs.Stat(filepath.Join(path, "index.html"))
|
||||
doRedirect = err != nil
|
||||
} else {
|
||||
doRedirect = false
|
||||
}
|
||||
}
|
||||
return
|
||||
case 200:
|
||||
if r2 := f.rewriteRequest(r, strings.TrimPrefix(redirect.To, baseURL.Path())); r2 != nil {
|
||||
requestURI = redirect.To
|
||||
r = r2
|
||||
}
|
||||
default:
|
||||
w.Header().Set("Content-Type", "")
|
||||
http.Redirect(w, r, redirect.To, redirect.Status)
|
||||
return
|
||||
}
|
||||
|
||||
if doRedirect {
|
||||
w.Header().Set(hugoHeaderRedirect, "true")
|
||||
switch redirect.Status {
|
||||
case 404:
|
||||
w.WriteHeader(404)
|
||||
file, err := fs.Open(strings.TrimPrefix(redirect.To, baseURL.Path()))
|
||||
if err == nil {
|
||||
defer file.Close()
|
||||
io.Copy(w, file)
|
||||
} else {
|
||||
fmt.Fprintln(w, "<h1>Page Not Found</h1>")
|
||||
}
|
||||
return
|
||||
case 200:
|
||||
if r2 := f.rewriteRequest(r, strings.TrimPrefix(redirect.To, baseURL.Path())); r2 != nil {
|
||||
requestURI = redirect.To
|
||||
r = r2
|
||||
}
|
||||
default:
|
||||
w.Header().Set("Content-Type", "")
|
||||
http.Redirect(w, r, redirect.To, redirect.Status)
|
||||
return
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if f.c.fastRenderMode && f.c.errState.buildErr() == nil {
|
||||
// Sec-Fetch-Mode should be sent by all recent browser versions, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Mode#navigate
|
||||
// Fall back to the file extension if not set.
|
||||
// The main take here is that we don't want to have CSS/JS files etc. partake in this logic.
|
||||
if r.Header.Get("Sec-Fetch-Mode") == "navigate" || strings.HasSuffix(requestURI, "/") || strings.HasSuffix(requestURI, "html") || strings.HasSuffix(requestURI, "htm") {
|
||||
if isNavigation(requestURI, r) {
|
||||
if !f.c.visitedURLs.Contains(requestURI) {
|
||||
// If not already on stack, re-render that single page.
|
||||
if err := f.c.partialReRender(requestURI); err != nil {
|
||||
@@ -1233,3 +1235,24 @@ func formatByteCount(b uint64) string {
|
||||
return fmt.Sprintf("%.1f %cB",
|
||||
float64(b)/float64(div), "kMGTPE"[exp])
|
||||
}
|
||||
|
||||
func canRedirect(requestURIWithoutQuery string, r *http.Request) bool {
|
||||
if r.Header.Get(hugoHeaderRedirect) != "" {
|
||||
return false
|
||||
}
|
||||
return isNavigation(requestURIWithoutQuery, r)
|
||||
}
|
||||
|
||||
// Sec-Fetch-Mode should be sent by all recent browser versions, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Mode#navigate
|
||||
// Fall back to the file extension if not set.
|
||||
// The main take here is that we don't want to have CSS/JS files etc. partake in this logic.
|
||||
func isNavigation(requestURIWithoutQuery string, r *http.Request) bool {
|
||||
return r.Header.Get("Sec-Fetch-Mode") == "navigate" || isPropablyHTMLRequest(requestURIWithoutQuery)
|
||||
}
|
||||
|
||||
func isPropablyHTMLRequest(requestURIWithoutQuery string) bool {
|
||||
if strings.HasSuffix(requestURIWithoutQuery, "/") || strings.HasSuffix(requestURIWithoutQuery, "html") || strings.HasSuffix(requestURIWithoutQuery, "htm") {
|
||||
return true
|
||||
}
|
||||
return !strings.Contains(requestURIWithoutQuery, ".")
|
||||
}
|
||||
|
||||
@@ -74,6 +74,16 @@ func IsTruthful(in any) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// IsMap reports whether v is a map.
|
||||
func IsMap(v any) bool {
|
||||
return reflect.ValueOf(v).Kind() == reflect.Map
|
||||
}
|
||||
|
||||
// IsSlice reports whether v is a slice.
|
||||
func IsSlice(v any) bool {
|
||||
return reflect.ValueOf(v).Kind() == reflect.Slice
|
||||
}
|
||||
|
||||
var zeroType = reflect.TypeOf((*types.Zeroer)(nil)).Elem()
|
||||
|
||||
// IsTruthfulValue returns whether the given value has a meaningful truth value.
|
||||
|
||||
+14
-5
@@ -414,11 +414,20 @@ func Deprecate(item, alternative string, version string) {
|
||||
DeprecateLevel(item, alternative, version, level)
|
||||
}
|
||||
|
||||
// DeprecateLevelMin informs about a deprecation starting at the given version, but with a minimum log level.
|
||||
func DeprecateLevelMin(item, alternative string, version string, minLevel logg.Level) {
|
||||
level := deprecationLogLevelFromVersion(version)
|
||||
if level < minLevel {
|
||||
level = minLevel
|
||||
}
|
||||
DeprecateLevel(item, alternative, version, level)
|
||||
}
|
||||
|
||||
// DeprecateLevel informs about a deprecation logging at the given level.
|
||||
func DeprecateLevel(item, alternative, version string, level logg.Level) {
|
||||
var msg string
|
||||
if level == logg.LevelError {
|
||||
msg = fmt.Sprintf("%s was deprecated in Hugo %s and will be removed in Hugo %s. %s", item, version, CurrentVersion.Next().ReleaseVersion(), alternative)
|
||||
msg = fmt.Sprintf("%s was deprecated in Hugo %s and subsequently removed. %s", item, version, alternative)
|
||||
} else {
|
||||
msg = fmt.Sprintf("%s was deprecated in Hugo %s and will be removed in a future release. %s", item, version, alternative)
|
||||
}
|
||||
@@ -434,11 +443,11 @@ func deprecationLogLevelFromVersion(ver string) logg.Level {
|
||||
to := CurrentVersion
|
||||
minorDiff := to.Minor - from.Minor
|
||||
switch {
|
||||
case minorDiff >= 12:
|
||||
// Start failing the build after about a year.
|
||||
case minorDiff >= 15:
|
||||
// Start failing the build after about 15 months.
|
||||
return logg.LevelError
|
||||
case minorDiff >= 6:
|
||||
// Start printing warnings after about six months.
|
||||
case minorDiff >= 3:
|
||||
// Start printing warnings after about 3 months.
|
||||
return logg.LevelWarn
|
||||
default:
|
||||
return logg.LevelInfo
|
||||
|
||||
@@ -57,11 +57,11 @@ func TestDeprecationLogLevelFromVersion(t *testing.T) {
|
||||
c.Assert(deprecationLogLevelFromVersion("0.55.0"), qt.Equals, logg.LevelError)
|
||||
ver := CurrentVersion
|
||||
c.Assert(deprecationLogLevelFromVersion(ver.String()), qt.Equals, logg.LevelInfo)
|
||||
ver.Minor -= 1
|
||||
c.Assert(deprecationLogLevelFromVersion(ver.String()), qt.Equals, logg.LevelInfo)
|
||||
ver.Minor -= 6
|
||||
ver.Minor -= 3
|
||||
c.Assert(deprecationLogLevelFromVersion(ver.String()), qt.Equals, logg.LevelWarn)
|
||||
ver.Minor -= 6
|
||||
ver.Minor -= 4
|
||||
c.Assert(deprecationLogLevelFromVersion(ver.String()), qt.Equals, logg.LevelWarn)
|
||||
ver.Minor -= 13
|
||||
c.Assert(deprecationLogLevelFromVersion(ver.String()), qt.Equals, logg.LevelError)
|
||||
|
||||
// Added just to find the threshold for where we can remove deprecated items.
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build extended
|
||||
// +build extended
|
||||
|
||||
package hugo
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !extended
|
||||
// +build !extended
|
||||
|
||||
package hugo
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build withdeploy
|
||||
// +build withdeploy
|
||||
|
||||
package hugo
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !withdeploy
|
||||
// +build !withdeploy
|
||||
|
||||
package hugo
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ package hugo
|
||||
// This should be the only one.
|
||||
var CurrentVersion = Version{
|
||||
Major: 0,
|
||||
Minor: 143,
|
||||
Minor: 145,
|
||||
PatchLevel: 0,
|
||||
Suffix: "-DEV",
|
||||
}
|
||||
|
||||
@@ -21,7 +21,15 @@ import (
|
||||
"github.com/bep/logg"
|
||||
)
|
||||
|
||||
func InitGlobalLogger(level logg.Level, panicOnWarnings bool) {
|
||||
// SetGlobalLogger sets the global logger.
|
||||
// This is used in a few places in Hugo, e.g. deprecated functions.
|
||||
func SetGlobalLogger(logger Logger) {
|
||||
logMu.Lock()
|
||||
defer logMu.Unlock()
|
||||
log = logger
|
||||
}
|
||||
|
||||
func initGlobalLogger(level logg.Level, panicOnWarnings bool) {
|
||||
logMu.Lock()
|
||||
defer logMu.Unlock()
|
||||
var logHookLast func(e *logg.Entry) error
|
||||
@@ -50,5 +58,5 @@ func Log() Logger {
|
||||
var log Logger
|
||||
|
||||
func init() {
|
||||
InitGlobalLogger(logg.LevelWarn, false)
|
||||
initGlobalLogger(logg.LevelWarn, false)
|
||||
}
|
||||
|
||||
@@ -73,10 +73,14 @@ func TestPrepareParams(t *testing.T) {
|
||||
for i, test := range tests {
|
||||
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
||||
// PrepareParams modifies input.
|
||||
prepareClone := PrepareParamsClone(test.input)
|
||||
PrepareParams(test.input)
|
||||
if !reflect.DeepEqual(test.expected, test.input) {
|
||||
t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, test.input)
|
||||
}
|
||||
if !reflect.DeepEqual(test.expected, prepareClone) {
|
||||
t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, prepareClone)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+40
-1
@@ -303,7 +303,7 @@ func toMergeStrategy(v any) ParamsMergeStrategy {
|
||||
}
|
||||
|
||||
// PrepareParams
|
||||
// * makes all the keys in the given map lower cased and will do so
|
||||
// * makes all the keys in the given map lower cased and will do so recursively.
|
||||
// * This will modify the map given.
|
||||
// * Any nested map[interface{}]interface{}, map[string]interface{},map[string]string will be converted to Params.
|
||||
// * Any _merge value will be converted to proper type and value.
|
||||
@@ -343,3 +343,42 @@ func PrepareParams(m Params) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PrepareParamsClone is like PrepareParams, but it does not modify the input.
|
||||
func PrepareParamsClone(m Params) Params {
|
||||
m2 := make(Params)
|
||||
for k, v := range m {
|
||||
var retyped bool
|
||||
lKey := strings.ToLower(k)
|
||||
if lKey == MergeStrategyKey {
|
||||
v = toMergeStrategy(v)
|
||||
retyped = true
|
||||
} else {
|
||||
switch vv := v.(type) {
|
||||
case map[any]any:
|
||||
var p Params = cast.ToStringMap(v)
|
||||
v = PrepareParamsClone(p)
|
||||
retyped = true
|
||||
case map[string]any:
|
||||
var p Params = v.(map[string]any)
|
||||
v = PrepareParamsClone(p)
|
||||
retyped = true
|
||||
case map[string]string:
|
||||
p := make(Params)
|
||||
for k, v := range vv {
|
||||
p[k] = v
|
||||
}
|
||||
v = p
|
||||
PrepareParams(p)
|
||||
retyped = true
|
||||
}
|
||||
}
|
||||
|
||||
if retyped || k != lKey {
|
||||
m2[lKey] = v
|
||||
} else {
|
||||
m2[k] = v
|
||||
}
|
||||
}
|
||||
return m2
|
||||
}
|
||||
|
||||
@@ -128,6 +128,9 @@ type Config struct {
|
||||
// <docsmeta>{"identifiers": ["markup"] }</docsmeta>
|
||||
Markup markup_config.Config `mapstructure:"-"`
|
||||
|
||||
// ContentTypes are the media types that's considered content in Hugo.
|
||||
ContentTypes *config.ConfigNamespace[map[string]media.ContentTypeConfig, media.ContentTypes] `mapstructure:"-"`
|
||||
|
||||
// The mediatypes configuration section maps the MIME type (a string) to a configuration object for that type.
|
||||
// <docsmeta>{"identifiers": ["mediatypes"], "refs": ["types:media:type"] }</docsmeta>
|
||||
MediaTypes *config.ConfigNamespace[map[string]media.MediaTypeConfig, media.Types] `mapstructure:"-"`
|
||||
@@ -424,6 +427,15 @@ func (c *Config) CompileConfig(logger loggers.Logger) error {
|
||||
c.Services.X.DisableInlineCSS = c.Services.Twitter.DisableInlineCSS
|
||||
}
|
||||
|
||||
// Legacy permalink tokens
|
||||
vs := fmt.Sprintf("%v", c.Permalinks)
|
||||
if strings.Contains(vs, ":filename") {
|
||||
hugo.Deprecate("the \":filename\" permalink token", "Use \":contentbasename\" instead.", "0.144.0")
|
||||
}
|
||||
if strings.Contains(vs, ":slugorfilename") {
|
||||
hugo.Deprecate("the \":slugorfilename\" permalink token", "Use \":slugorcontentbasename\" instead.", "0.144.0")
|
||||
}
|
||||
|
||||
c.C = &ConfigCompiled{
|
||||
Timeout: timeout,
|
||||
BaseURL: baseURL,
|
||||
@@ -433,7 +445,6 @@ func (c *Config) CompileConfig(logger loggers.Logger) error {
|
||||
IgnoredLogs: ignoredLogIDs,
|
||||
KindOutputFormats: kindOutputFormats,
|
||||
DefaultOutputFormat: defaultOutputFormat,
|
||||
ContentTypes: media.DefaultContentTypes.FromTypes(c.MediaTypes.Config),
|
||||
CreateTitle: helpers.GetTitleFunc(c.TitleCaseStyle),
|
||||
IsUglyURLSection: isUglyURL,
|
||||
IgnoreFile: ignoreFile,
|
||||
@@ -471,7 +482,6 @@ type ConfigCompiled struct {
|
||||
ServerInterface string
|
||||
KindOutputFormats map[string]output.Formats
|
||||
DefaultOutputFormat output.Format
|
||||
ContentTypes media.ContentTypes
|
||||
DisabledKinds map[string]bool
|
||||
DisabledLanguages map[string]bool
|
||||
IgnoredLogs map[string]bool
|
||||
@@ -839,7 +849,7 @@ func (c *Configs) Init() error {
|
||||
c.Languages = languages
|
||||
c.LanguagesDefaultFirst = languagesDefaultFirst
|
||||
|
||||
c.ContentPathParser = &paths.PathParser{LanguageIndex: languagesDefaultFirst.AsIndexSet(), IsLangDisabled: c.Base.IsLangDisabled, IsContentExt: c.Base.C.ContentTypes.IsContentSuffix}
|
||||
c.ContentPathParser = &paths.PathParser{LanguageIndex: languagesDefaultFirst.AsIndexSet(), IsLangDisabled: c.Base.IsLangDisabled, IsContentExt: c.Base.ContentTypes.Config.IsContentSuffix}
|
||||
|
||||
c.configLangs = make([]config.AllProvider, len(c.Languages))
|
||||
for i, l := range c.LanguagesDefaultFirst {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
qt "github.com/frankban/quicktest"
|
||||
"github.com/gohugoio/hugo/config/allconfig"
|
||||
"github.com/gohugoio/hugo/hugolib"
|
||||
"github.com/gohugoio/hugo/media"
|
||||
)
|
||||
|
||||
func TestDirsMount(t *testing.T) {
|
||||
@@ -97,7 +98,7 @@ suffixes = ["html", "xhtml"]
|
||||
b := hugolib.Test(t, files)
|
||||
|
||||
conf := b.H.Configs.Base
|
||||
contentTypes := conf.C.ContentTypes
|
||||
contentTypes := conf.ContentTypes.Config
|
||||
|
||||
b.Assert(contentTypes.HTML.Suffixes(), qt.DeepEquals, []string{"html", "xhtml"})
|
||||
b.Assert(contentTypes.Markdown.Suffixes(), qt.DeepEquals, []string{"md", "mdown", "markdown"})
|
||||
@@ -215,3 +216,21 @@ weight = 3
|
||||
b := hugolib.Test(t, files)
|
||||
b.Assert(b.H.Configs.LanguageConfigSlice[0].Title, qt.Equals, `TITLE_DE`)
|
||||
}
|
||||
|
||||
func TestContentTypesDefault(t *testing.T) {
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
baseURL = "https://example.com"
|
||||
|
||||
|
||||
`
|
||||
|
||||
b := hugolib.Test(t, files)
|
||||
|
||||
ct := b.H.Configs.Base.ContentTypes
|
||||
c := ct.Config
|
||||
s := ct.SourceStructure.(map[string]media.ContentTypeConfig)
|
||||
|
||||
b.Assert(c.IsContentFile("foo.md"), qt.Equals, true)
|
||||
b.Assert(len(s), qt.Equals, 6)
|
||||
}
|
||||
|
||||
@@ -163,6 +163,15 @@ var allDecoderSetups = map[string]decodeWeight{
|
||||
return err
|
||||
},
|
||||
},
|
||||
"contenttypes": {
|
||||
key: "contenttypes",
|
||||
weight: 100, // This needs to be decoded after media types.
|
||||
decode: func(d decodeWeight, p decodeConfig) error {
|
||||
var err error
|
||||
p.c.ContentTypes, err = media.DecodeContentTypes(p.p.GetStringMap(d.key), p.c.MediaTypes.Config)
|
||||
return err
|
||||
},
|
||||
},
|
||||
"mediatypes": {
|
||||
key: "mediatypes",
|
||||
decode: func(d decodeWeight, p decodeConfig) error {
|
||||
|
||||
@@ -145,7 +145,7 @@ func (c ConfigLanguage) NewIdentityManager(name string, opts ...identity.Manager
|
||||
}
|
||||
|
||||
func (c ConfigLanguage) ContentTypes() config.ContentTypesProvider {
|
||||
return c.config.C.ContentTypes
|
||||
return c.config.ContentTypes.Config
|
||||
}
|
||||
|
||||
// GetConfigSection is mostly used in tests. The switch statement isn't complete, but what's in use.
|
||||
|
||||
@@ -91,7 +91,7 @@ func LoadConfig(d ConfigSourceDescriptor) (*Configs, error) {
|
||||
return nil, fmt.Errorf("failed to init config: %w", err)
|
||||
}
|
||||
|
||||
loggers.InitGlobalLogger(d.Logger.Level(), configs.Base.PanicOnWarning)
|
||||
loggers.SetGlobalLogger(d.Logger)
|
||||
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
+94
-23
@@ -15,6 +15,7 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -226,7 +227,22 @@ type Server struct {
|
||||
Redirects []Redirect
|
||||
|
||||
compiledHeaders []glob.Glob
|
||||
compiledRedirects []glob.Glob
|
||||
compiledRedirects []redirect
|
||||
}
|
||||
|
||||
type redirect struct {
|
||||
from glob.Glob
|
||||
fromRe *regexp.Regexp
|
||||
headers map[string]glob.Glob
|
||||
}
|
||||
|
||||
func (r redirect) matchHeader(header http.Header) bool {
|
||||
for k, v := range r.headers {
|
||||
if !v.Match(header.Get(k)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Server) CompileConfig(logger loggers.Logger) error {
|
||||
@@ -234,10 +250,41 @@ func (s *Server) CompileConfig(logger loggers.Logger) error {
|
||||
return nil
|
||||
}
|
||||
for _, h := range s.Headers {
|
||||
s.compiledHeaders = append(s.compiledHeaders, glob.MustCompile(h.For))
|
||||
g, err := glob.Compile(h.For)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to compile Headers glob %q: %w", h.For, err)
|
||||
}
|
||||
s.compiledHeaders = append(s.compiledHeaders, g)
|
||||
}
|
||||
for _, r := range s.Redirects {
|
||||
s.compiledRedirects = append(s.compiledRedirects, glob.MustCompile(r.From))
|
||||
if r.From == "" && r.FromRe == "" {
|
||||
return fmt.Errorf("redirects must have either From or FromRe set")
|
||||
}
|
||||
rd := redirect{
|
||||
headers: make(map[string]glob.Glob),
|
||||
}
|
||||
if r.From != "" {
|
||||
g, err := glob.Compile(r.From)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to compile Redirect glob %q: %w", r.From, err)
|
||||
}
|
||||
rd.from = g
|
||||
}
|
||||
if r.FromRe != "" {
|
||||
re, err := regexp.Compile(r.FromRe)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to compile Redirect regexp %q: %w", r.FromRe, err)
|
||||
}
|
||||
rd.fromRe = re
|
||||
}
|
||||
for k, v := range r.FromHeaders {
|
||||
g, err := glob.Compile(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to compile Redirect header glob %q: %w", v, err)
|
||||
}
|
||||
rd.headers[k] = g
|
||||
}
|
||||
s.compiledRedirects = append(s.compiledRedirects, rd)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -266,22 +313,42 @@ func (s *Server) MatchHeaders(pattern string) []types.KeyValueStr {
|
||||
return matches
|
||||
}
|
||||
|
||||
func (s *Server) MatchRedirect(pattern string) Redirect {
|
||||
func (s *Server) MatchRedirect(pattern string, header http.Header) Redirect {
|
||||
if s.compiledRedirects == nil {
|
||||
return Redirect{}
|
||||
}
|
||||
|
||||
pattern = strings.TrimSuffix(pattern, "index.html")
|
||||
|
||||
for i, g := range s.compiledRedirects {
|
||||
for i, r := range s.compiledRedirects {
|
||||
redir := s.Redirects[i]
|
||||
|
||||
// No redirect to self.
|
||||
if redir.To == pattern {
|
||||
return Redirect{}
|
||||
var found bool
|
||||
|
||||
if r.from != nil {
|
||||
if r.from.Match(pattern) {
|
||||
found = header == nil || r.matchHeader(header)
|
||||
// We need to do regexp group replacements if needed.
|
||||
}
|
||||
}
|
||||
|
||||
if g.Match(pattern) {
|
||||
if r.fromRe != nil {
|
||||
m := r.fromRe.FindStringSubmatch(pattern)
|
||||
if m != nil {
|
||||
if !found {
|
||||
found = header == nil || r.matchHeader(header)
|
||||
}
|
||||
|
||||
if found {
|
||||
// Replace $1, $2 etc. in To.
|
||||
for i, g := range m[1:] {
|
||||
redir.To = strings.ReplaceAll(redir.To, fmt.Sprintf("$%d", i+1), g)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
return redir
|
||||
}
|
||||
}
|
||||
@@ -295,8 +362,22 @@ type Headers struct {
|
||||
}
|
||||
|
||||
type Redirect struct {
|
||||
// From is the Glob pattern to match.
|
||||
// One of From or FromRe must be set.
|
||||
From string
|
||||
To string
|
||||
|
||||
// FromRe is the regexp to match.
|
||||
// This regexp can contain group matches (e.g. $1) that can be used in the To field.
|
||||
// One of From or FromRe must be set.
|
||||
FromRe string
|
||||
|
||||
// To is the target URL.
|
||||
To string
|
||||
|
||||
// Headers to match for the redirect.
|
||||
// This maps the HTTP header name to a Glob pattern with values to match.
|
||||
// If the map is empty, the redirect will always be triggered.
|
||||
FromHeaders map[string]string
|
||||
|
||||
// HTTP status code to use for the redirect.
|
||||
// A status code of 200 will trigger a URL rewrite.
|
||||
@@ -369,7 +450,7 @@ func (c *CacheBuster) CompileConfig(logger loggers.Logger) error {
|
||||
}
|
||||
|
||||
func (r Redirect) IsZero() bool {
|
||||
return r.From == ""
|
||||
return r.From == "" && r.FromRe == ""
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -383,17 +464,7 @@ func DecodeServer(cfg Provider) (Server, error) {
|
||||
_ = mapstructure.WeakDecode(cfg.GetStringMap("server"), s)
|
||||
|
||||
for i, redir := range s.Redirects {
|
||||
// Get it in line with the Hugo server for OK responses.
|
||||
// We currently treat the 404 as a special case, they are always "ugly", so keep them as is.
|
||||
if redir.Status != 404 {
|
||||
redir.To = strings.TrimSuffix(redir.To, "index.html")
|
||||
if !strings.HasPrefix(redir.To, "https") && !strings.HasSuffix(redir.To, "/") {
|
||||
// There are some tricky infinite loop situations when dealing
|
||||
// when the target does not have a trailing slash.
|
||||
// This can certainly be handled better, but not time for that now.
|
||||
return Server{}, fmt.Errorf("unsupported redirect to value %q in server config; currently this must be either a remote destination or a local folder, e.g. \"/blog/\" or \"/blog/index.html\"", redir.To)
|
||||
}
|
||||
}
|
||||
redir.To = strings.TrimSuffix(redir.To, "index.html")
|
||||
s.Redirects[i] = redir
|
||||
}
|
||||
|
||||
@@ -401,7 +472,7 @@ func DecodeServer(cfg Provider) (Server, error) {
|
||||
// Set up a default redirect for 404s.
|
||||
s.Redirects = []Redirect{
|
||||
{
|
||||
From: "**",
|
||||
From: "/**",
|
||||
To: "/404.html",
|
||||
Status: 404,
|
||||
},
|
||||
|
||||
+41
-35
@@ -71,7 +71,28 @@ X-Content-Type-Options = "nosniff"
|
||||
|
||||
[[server.redirects]]
|
||||
from = "/foo/**"
|
||||
to = "/foo/index.html"
|
||||
to = "/baz/index.html"
|
||||
status = 200
|
||||
|
||||
[[server.redirects]]
|
||||
from = "/loop/**"
|
||||
to = "/loop/foo/"
|
||||
status = 200
|
||||
|
||||
[[server.redirects]]
|
||||
from = "/b/**"
|
||||
fromRe = "/b/(.*)/"
|
||||
to = "/baz/$1/"
|
||||
status = 200
|
||||
|
||||
[[server.redirects]]
|
||||
fromRe = "/c/(.*)/"
|
||||
to = "/boo/$1/"
|
||||
status = 200
|
||||
|
||||
[[server.redirects]]
|
||||
fromRe = "/d/(.*)/"
|
||||
to = "/boo/$1/"
|
||||
status = 200
|
||||
|
||||
[[server.redirects]]
|
||||
@@ -79,11 +100,6 @@ from = "/google/**"
|
||||
to = "https://google.com/"
|
||||
status = 301
|
||||
|
||||
[[server.redirects]]
|
||||
from = "/**"
|
||||
to = "/default/index.html"
|
||||
status = 301
|
||||
|
||||
|
||||
|
||||
`, "toml")
|
||||
@@ -100,45 +116,35 @@ status = 301
|
||||
{Key: "X-XSS-Protection", Value: "1; mode=block"},
|
||||
})
|
||||
|
||||
c.Assert(s.MatchRedirect("/foo/bar/baz"), qt.DeepEquals, Redirect{
|
||||
c.Assert(s.MatchRedirect("/foo/bar/baz", nil), qt.DeepEquals, Redirect{
|
||||
From: "/foo/**",
|
||||
To: "/foo/",
|
||||
To: "/baz/",
|
||||
Status: 200,
|
||||
})
|
||||
|
||||
c.Assert(s.MatchRedirect("/someother"), qt.DeepEquals, Redirect{
|
||||
From: "/**",
|
||||
To: "/default/",
|
||||
Status: 301,
|
||||
c.Assert(s.MatchRedirect("/foo/bar/", nil), qt.DeepEquals, Redirect{
|
||||
From: "/foo/**",
|
||||
To: "/baz/",
|
||||
Status: 200,
|
||||
})
|
||||
|
||||
c.Assert(s.MatchRedirect("/google/foo"), qt.DeepEquals, Redirect{
|
||||
c.Assert(s.MatchRedirect("/b/c/", nil), qt.DeepEquals, Redirect{
|
||||
From: "/b/**",
|
||||
FromRe: "/b/(.*)/",
|
||||
To: "/baz/c/",
|
||||
Status: 200,
|
||||
})
|
||||
|
||||
c.Assert(s.MatchRedirect("/c/d/", nil).To, qt.Equals, "/boo/d/")
|
||||
c.Assert(s.MatchRedirect("/c/d/e/", nil).To, qt.Equals, "/boo/d/e/")
|
||||
|
||||
c.Assert(s.MatchRedirect("/someother", nil), qt.DeepEquals, Redirect{})
|
||||
|
||||
c.Assert(s.MatchRedirect("/google/foo", nil), qt.DeepEquals, Redirect{
|
||||
From: "/google/**",
|
||||
To: "https://google.com/",
|
||||
Status: 301,
|
||||
})
|
||||
|
||||
// No redirect loop, please.
|
||||
c.Assert(s.MatchRedirect("/default/index.html"), qt.DeepEquals, Redirect{})
|
||||
c.Assert(s.MatchRedirect("/default/"), qt.DeepEquals, Redirect{})
|
||||
|
||||
for _, errorCase := range []string{
|
||||
`[[server.redirects]]
|
||||
from = "/**"
|
||||
to = "/file"
|
||||
status = 301`,
|
||||
`[[server.redirects]]
|
||||
from = "/**"
|
||||
to = "/foo/file.html"
|
||||
status = 301`,
|
||||
} {
|
||||
|
||||
cfg, err := FromConfigString(errorCase, "toml")
|
||||
c.Assert(err, qt.IsNil)
|
||||
_, err = DecodeServer(cfg)
|
||||
c.Assert(err, qt.Not(qt.IsNil))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildConfigCacheBusters(t *testing.T) {
|
||||
|
||||
@@ -15,7 +15,6 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -26,42 +25,6 @@ import (
|
||||
"github.com/gohugoio/hugo/common/maps"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
// ConfigRootKeysSet contains all of the config map root keys.
|
||||
ConfigRootKeysSet = map[string]bool{
|
||||
"build": true,
|
||||
"caches": true,
|
||||
"cascade": true,
|
||||
"frontmatter": true,
|
||||
"languages": true,
|
||||
"imaging": true,
|
||||
"markup": true,
|
||||
"mediatypes": true,
|
||||
"menus": true,
|
||||
"minify": true,
|
||||
"module": true,
|
||||
"outputformats": true,
|
||||
"params": true,
|
||||
"permalinks": true,
|
||||
"related": true,
|
||||
"sitemap": true,
|
||||
"privacy": true,
|
||||
"security": true,
|
||||
"taxonomies": true,
|
||||
}
|
||||
|
||||
// ConfigRootKeys is a sorted version of ConfigRootKeysSet.
|
||||
ConfigRootKeys []string
|
||||
)
|
||||
|
||||
func init() {
|
||||
for k := range ConfigRootKeysSet {
|
||||
ConfigRootKeys = append(ConfigRootKeys, k)
|
||||
}
|
||||
sort.Strings(ConfigRootKeys)
|
||||
}
|
||||
|
||||
// New creates a Provider backed by an empty maps.Params.
|
||||
func New() Provider {
|
||||
return &defaultConfigProvider{
|
||||
|
||||
@@ -36,10 +36,6 @@ respectDoNotTrack = true
|
||||
[privacy.instagram]
|
||||
disable = true
|
||||
simple = true
|
||||
[privacy.twitter]
|
||||
disable = true
|
||||
enableDNT = true
|
||||
simple = true
|
||||
[privacy.x]
|
||||
disable = true
|
||||
enableDNT = true
|
||||
@@ -63,8 +59,8 @@ simple = true
|
||||
got := []bool{
|
||||
pc.Disqus.Disable, pc.GoogleAnalytics.Disable,
|
||||
pc.GoogleAnalytics.RespectDoNotTrack, pc.Instagram.Disable,
|
||||
pc.Instagram.Simple, pc.Twitter.Disable, pc.Twitter.EnableDNT,
|
||||
pc.Twitter.Simple, pc.Vimeo.Disable, pc.Vimeo.EnableDNT, pc.Vimeo.Simple,
|
||||
pc.Instagram.Simple,
|
||||
pc.Vimeo.Disable, pc.Vimeo.EnableDNT, pc.Vimeo.Simple,
|
||||
pc.YouTube.PrivacyEnhanced, pc.YouTube.Disable, pc.X.Disable, pc.X.EnableDNT,
|
||||
pc.X.Simple,
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build withdeploy
|
||||
// +build withdeploy
|
||||
|
||||
package deploy
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build withdeploy
|
||||
// +build withdeploy
|
||||
|
||||
package deploy
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !solaris && withdeploy
|
||||
// +build !solaris,withdeploy
|
||||
|
||||
package deploy
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build withdeploy
|
||||
// +build withdeploy
|
||||
|
||||
package deploy
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build withdeploy
|
||||
// +build withdeploy
|
||||
|
||||
package deployconfig
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build withdeploy
|
||||
// +build withdeploy
|
||||
|
||||
package deploy
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Config file for codespell.
|
||||
# https://github.com/codespell-project/codespell#using-a-config-file
|
||||
|
||||
[codespell]
|
||||
|
||||
# Comma separated list of dirs to be skipped.
|
||||
skip = _vendor,.cspell.json,chroma.css,chroma_dark.css
|
||||
|
||||
# Comma separated list of words to be ignored. Words must be lowercased.
|
||||
ignore-words-list = abl,edn,te,ue,trys,januar,womens,crossreferences
|
||||
|
||||
# Check file names as well.
|
||||
check-filenames = true
|
||||
@@ -68,6 +68,7 @@
|
||||
"# ----------------------------------------------------------------------",
|
||||
"# cspell: ignore hugo terminology",
|
||||
"# ----------------------------------------------------------------------",
|
||||
"alignx",
|
||||
"attrlink",
|
||||
"canonify",
|
||||
"codeowners",
|
||||
@@ -85,6 +86,7 @@
|
||||
"stringifier",
|
||||
"struct",
|
||||
"toclevels",
|
||||
"unmarshal",
|
||||
"unpublishdate",
|
||||
"zgotmplz",
|
||||
"# ----------------------------------------------------------------------",
|
||||
@@ -158,6 +160,8 @@
|
||||
"# cspell: ignore miscellaneous",
|
||||
"# ----------------------------------------------------------------------",
|
||||
"achristie",
|
||||
"ccpa",
|
||||
"crpa",
|
||||
"ddmaurier",
|
||||
"dring",
|
||||
"fleqn",
|
||||
@@ -171,6 +175,7 @@
|
||||
"rsmith",
|
||||
"tdewolff",
|
||||
"tjones",
|
||||
"vcard",
|
||||
"wcag",
|
||||
"xfeff"
|
||||
]
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
---
|
||||
name: Default
|
||||
about: This is the default issue template.
|
||||
labels:
|
||||
- NeedsTriage
|
||||
---
|
||||
+5
@@ -20,3 +20,8 @@ jobs:
|
||||
incremental_files_only: true
|
||||
inline: warning
|
||||
strict: false
|
||||
- uses: codespell-project/actions-codespell@v2
|
||||
with:
|
||||
check_filenames: true
|
||||
check_hidden: true
|
||||
# by default, codespell uses configuration from the .codespellrc
|
||||
|
||||
+9
-6
@@ -1,10 +1,13 @@
|
||||
.DS_Store
|
||||
.hugo_build.lock
|
||||
/.idea
|
||||
/.vscode
|
||||
/public
|
||||
/dist
|
||||
node_modules
|
||||
/public
|
||||
hugo_stats.json
|
||||
node_modules/
|
||||
nohup.out
|
||||
.DS_Store
|
||||
trace.out
|
||||
.hugo_build.lock
|
||||
resources/_gen/images/
|
||||
package-lock.json
|
||||
public/
|
||||
resources/
|
||||
trace.out
|
||||
+2
-200
@@ -1,201 +1,3 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
See [content/LICENSE.md](content/LICENSE.md) for the license of the content of this repository.
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
The theme (layouts, CSS, JavaScript etc.) of this repository has no open source license. It is custom made for the Hugo sites and is not meant for reuse.
|
||||
@@ -16,3 +16,12 @@ Please see the [contributing] section for guidelines, examples, and process.
|
||||
[friends]: https://github.com/gohugoio/hugo/graphs/contributors
|
||||
[go]: https://go.dev/
|
||||
[contributing]: https://gohugo.io/contribute/documentation
|
||||
|
||||
# Install
|
||||
|
||||
```bash
|
||||
npm i
|
||||
hugo server
|
||||
```
|
||||
|
||||
**Note:** We're working on removing the need to run `npm i` for local development. Stay tuned.
|
||||
File diff suppressed because one or more lines are too long
@@ -1,21 +0,0 @@
|
||||
.animated {
|
||||
animation-duration: .5s;
|
||||
animation-fill-mode: forwards;
|
||||
animation-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.fadeIn {
|
||||
animation-name: fadeIn;
|
||||
}
|
||||
.animated-delay-1 {
|
||||
animation-delay: 0.5s;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/* These styles enhance the home page carousel, located here: themes/gohugoioTheme/layouts/partials/home-page-sections/showcase.html */
|
||||
.overflow-x-scroll{
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
.row {
|
||||
transition: 450ms transform;
|
||||
font-size: 0;
|
||||
}
|
||||
.tile {
|
||||
transition: 450ms all;
|
||||
}
|
||||
.details {
|
||||
background: -webkit-gradient(linear, left bottom, left top, from(rgba(0,0,0,0.9)), to(rgba(0,0,0,0)));
|
||||
background: linear-gradient(to top, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0) 100%);
|
||||
transition: 450ms opacity;
|
||||
}
|
||||
.tile:hover .details {
|
||||
opacity: 1;
|
||||
}
|
||||
.row:hover .tile {
|
||||
opacity: 0.3;
|
||||
}
|
||||
.row:hover .tile:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
.chroma .lntable pre {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.chroma .lntable pre code {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 2px 3px;
|
||||
margin: 0;
|
||||
font-size: 93.75%;
|
||||
background-color: rgba(27,31,35,0.05);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
padding: 1.5em 1.5em;
|
||||
font-size: .875rem;
|
||||
line-height: 2;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
white-space: pre;
|
||||
hyphens: none;
|
||||
position: relative;
|
||||
border-width: 1px;
|
||||
border-color: #ccc;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
/* The Pygments highlighter comes with its own styles. */
|
||||
.highlight pre {
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
padding: 0.5em;
|
||||
font-size: .875rem;
|
||||
}
|
||||
|
||||
|
||||
/*We are adding the copy button content here so we can change it with javascript. See the "Clipboard scripts"*/
|
||||
.copy:after {
|
||||
content: "Copy"
|
||||
}
|
||||
.copied:after {
|
||||
content: "Copied"
|
||||
}
|
||||
|
||||
@media (--breakpoint-large) {
|
||||
.full-width
|
||||
{
|
||||
/*width: 100vw;
|
||||
position: relative;
|
||||
left: 50%;
|
||||
right: 50%;
|
||||
margin-left: -50vw;
|
||||
margin-right: -50vw;*/
|
||||
/*width: 60vw;*/
|
||||
/*position: relative;
|
||||
left: 50%;
|
||||
right: 50%;*/
|
||||
/*margin-left: -30vw;*/
|
||||
margin-right: -30vw;
|
||||
max-width: 100vw;
|
||||
}
|
||||
}
|
||||
|
||||
.code-block .line-numbers-rows {
|
||||
background: #2f3a46;
|
||||
border: none;
|
||||
bottom: -50px;
|
||||
color: #98a4b3;
|
||||
left: -178px;
|
||||
padding: 50px 0;
|
||||
top: -50px;
|
||||
width: 138px
|
||||
}
|
||||
|
||||
.code-block .line-numbers-rows>span:before {
|
||||
color: inherit;
|
||||
padding-right: 30px
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
.primary-color {color: var(--primary-color)}
|
||||
.bg-primary-color {background-color: var(--primary-color)}
|
||||
.hover-bg-primary-color:hover {background-color: var(--primary-color)}
|
||||
|
||||
.primary-color-dark {color: var(--primary-color-dark)}
|
||||
.bg-primary-color-dark {background-color: var(--primary-color-dark)}
|
||||
.hover-bg-primary-color-dark:hover {background-color: var(--primary-color-dark)}
|
||||
|
||||
.primary-color-light {color: var(--primary-color-light)}
|
||||
.bg-primary-color-light {background-color: var(--primary-color-light)}
|
||||
.hover-bg-primary-color-light:hover {background-color: var(--primary-color-light)}
|
||||
|
||||
.accent-color {color: var(--accent-color)}
|
||||
.bg-accent-color {background-color: var(--accent-color)}
|
||||
.hover-bg-accent-color:hover {background-color: var(--accent-color)}
|
||||
|
||||
.accent-color-light {color: var(--accent-color-light)}
|
||||
.hover-accent-color-light:hover {color: var(--accent-color-light)}
|
||||
.bg-accent-color-light {background-color: var(--accent-color-light)}
|
||||
.hover-bg-accent-color-light:hover {background-color: var(--accent-color-light)}
|
||||
|
||||
.accent-color-dark {color: var(--accent-color-dark)}
|
||||
.bg-accent-color-dark {background-color: var(--accent-color-dark)}
|
||||
.hover-bg-accent-color-dark:hover {background-color: var(--accent-color-dark)}
|
||||
|
||||
.text-color-primary {color: var(--text-color-primary)}
|
||||
.text-on-primary-color {color: var(--text-on-primary-color)}
|
||||
.text-color-secondary {color: var(--text-color-secondary)}
|
||||
.text-color-disabled {color: var(--text-color-disabled)}
|
||||
.divider-color {color: var(--divider-color)}
|
||||
.warn-color {color: var(--warn-color)}
|
||||
|
||||
|
||||
.nested-links a {
|
||||
color: var(--primary-color);
|
||||
text-decoration: none;
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
.column-count-2 {column-count: 1}
|
||||
.column-gap-1 {column-gap: 0}
|
||||
.break-inside-avoid {break-inside: auto}
|
||||
|
||||
|
||||
@media (--breakpoint-large) {
|
||||
.column-count-3-l {column-count: 3}
|
||||
.column-count-2-l {column-count: 2}
|
||||
.column-gap-1-l {column-gap: 1}
|
||||
.break-inside-avoid-l {break-inside: avoid}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
.prose table {
|
||||
width: 100%;
|
||||
margin-bottom: 3em;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
font-size: 1em;
|
||||
border: 1px solid var(--light-gray);
|
||||
& th {
|
||||
background-color: var(--primary-color);
|
||||
border-bottom: 1px solid var(--primary-color);
|
||||
color: white;
|
||||
font-weight: 400;
|
||||
|
||||
text-align: left;
|
||||
padding: .375em .5em;
|
||||
}
|
||||
|
||||
& td, & tc {
|
||||
padding: .75em .5em;
|
||||
text-align: left;
|
||||
border-right: 1px solid var(--light-gray);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.prose table tr:nth-child(even) {
|
||||
background-color: var(--light-gray);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
.prose ul, .prose ol {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
.prose ul li, .prose ol li {
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
.prose li:hover {
|
||||
background-color: var(--light-gray)
|
||||
}
|
||||
.prose ::selection {
|
||||
background: var(--primary-color); /* WebKit/Blink Browsers */
|
||||
color: white;
|
||||
}
|
||||
|
||||
.prose-glossary h3 {
|
||||
margin-top: 0;
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
.prose-glossary h3:first-of-type {
|
||||
margin-top: 3em;
|
||||
}
|
||||
|
||||
.prose-glossary h3 ~ p {
|
||||
margin: 0.5em 0 2em 0;
|
||||
}
|
||||
|
||||
body {
|
||||
|
||||
line-height: 1.45;
|
||||
|
||||
}
|
||||
|
||||
p {margin-bottom: 1.3em;}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
margin: 1.414em 0 0.5em;
|
||||
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 0;
|
||||
font-size: 2.441em;
|
||||
}
|
||||
|
||||
h2 {font-size: 1.953em;}
|
||||
|
||||
h3 {font-size: 1.563em;}
|
||||
|
||||
h4 {font-size: 1.25em;}
|
||||
|
||||
small, .font_small {font-size: 0.8em;}
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
|
||||
dl dt {
|
||||
font-weight: bold;
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
dd {
|
||||
margin: .5em 0 2em 0;
|
||||
padding: 0;
|
||||
}
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
.note,
|
||||
.warning {
|
||||
|
||||
border-left-width: 4px;
|
||||
border-left-style: solid;
|
||||
position: relative;
|
||||
border-color: var(--primary-color);
|
||||
|
||||
display: block;
|
||||
}
|
||||
.note #exclamation-icon,
|
||||
.warning #exclamation-icon {
|
||||
|
||||
fill: var(--primary-color);
|
||||
position: absolute;
|
||||
top: 35%;
|
||||
left: -12px;
|
||||
/*background-color: white;*/
|
||||
}
|
||||
|
||||
.admonition-content {
|
||||
display: block;
|
||||
margin: 0px;
|
||||
padding: .125em 1em;
|
||||
/*margin-left: 1em;*/
|
||||
margin-top: 2em;
|
||||
margin-bottom: 2em;
|
||||
overflow-x: auto;
|
||||
/*font-size: .9375em;*/
|
||||
background-color: var(--black-05);
|
||||
}
|
||||
|
||||
|
||||
.hide-child-menu .child-menu {
|
||||
display: none;
|
||||
}
|
||||
.hide-child-menu:hover .child-menu,
|
||||
.hide-child-menu:focus .child-menu,
|
||||
.hide-child-menu:active .child-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
/*documentation-copy headings exaggerate spacing and size to chunk content */
|
||||
.documentation-copy h2 {
|
||||
margin-top: 3em;
|
||||
&.minor {
|
||||
font-size: inherit;
|
||||
margin-top: inherit;
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
.f2-fluid {
|
||||
font-size: 2.25rem;
|
||||
}
|
||||
|
||||
@media (--breakpoint-large) {
|
||||
.f2-fluid {
|
||||
font-size: 1.25rem;
|
||||
font-size: calc(0.875rem + 0.5 * ((100vw - 20rem) / 60));
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/* From https://www.cssfontstack.com */
|
||||
code, .code, pre code, .highlight pre {
|
||||
font-family: 'inconsolata',Menlo,Monaco,'Courier New',monospace;
|
||||
}
|
||||
|
||||
.sans-serif {
|
||||
font-family: 'Muli', Avenir, 'Helvetica Neue', Helvetica, Roboto, Noto, 'Segoe UI', Arial, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
.serif {
|
||||
font-family: Palatino,"Palatino Linotype","Palatino LT STD","Book Antiqua",Georgia,serif;
|
||||
}
|
||||
|
||||
/* Monospaced Typefaces (for code) */
|
||||
|
||||
|
||||
.courier {
|
||||
font-family: 'Courier Next',
|
||||
courier,
|
||||
monospace;
|
||||
}
|
||||
|
||||
|
||||
/* Sans-Serif Typefaces */
|
||||
|
||||
.helvetica {
|
||||
font-family: 'helvetica neue', helvetica,
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
.avenir {
|
||||
font-family: 'avenir next', avenir,
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
|
||||
/* Serif Typefaces */
|
||||
|
||||
.athelas {
|
||||
font-family: athelas,
|
||||
georgia,
|
||||
serif;
|
||||
}
|
||||
|
||||
.georgia {
|
||||
font-family: georgia,
|
||||
serif;
|
||||
}
|
||||
|
||||
.times {
|
||||
font-family: times,
|
||||
serif;
|
||||
}
|
||||
|
||||
.bodoni {
|
||||
font-family: "Bodoni MT",
|
||||
serif;
|
||||
}
|
||||
|
||||
.calisto {
|
||||
font-family: "Calisto MT",
|
||||
serif;
|
||||
}
|
||||
|
||||
.garamond {
|
||||
font-family: garamond,
|
||||
serif;
|
||||
}
|
||||
|
||||
.baskerville {
|
||||
font-family: baskerville,
|
||||
serif;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
.header-link:after {
|
||||
position: relative;
|
||||
left: 0.5em;
|
||||
opacity: 0;
|
||||
font-size: 0.8em;
|
||||
-moz-transition: opacity 0.2s ease-in-out 0.1s;
|
||||
-ms-transition: opacity 0.2s ease-in-out 0.1s;
|
||||
}
|
||||
h2:hover .header-link,
|
||||
h3:hover .header-link,
|
||||
h4:hover .header-link,
|
||||
h5:hover .header-link,
|
||||
h6:hover .header-link {
|
||||
opacity: 1;
|
||||
}
|
||||
Generated
-52
@@ -1,52 +0,0 @@
|
||||
/* pagination.html: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/template_embedded.go#L117 */
|
||||
.pagination {
|
||||
margin: 3rem 0;
|
||||
}
|
||||
|
||||
.pagination li {
|
||||
display: inline-block;
|
||||
margin-right: .375rem;
|
||||
font-size: .875rem;
|
||||
margin-bottom: 2.5em;
|
||||
}
|
||||
.pagination li a {
|
||||
padding: .5rem .625rem;
|
||||
background-color: white;
|
||||
color: #333;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.pagination li.disabled {
|
||||
display: none;
|
||||
}
|
||||
.pagination li.active a:link,
|
||||
.pagination li.active a:active,
|
||||
.pagination li.active a:visited {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
/* Hides non-meaningful TOC items*/
|
||||
#TableOfContents ul li ul li ul li{
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
#TableOfContents ul li {
|
||||
color: black;
|
||||
display: block;
|
||||
margin-bottom: .375em;
|
||||
line-height: 1.375;
|
||||
}
|
||||
|
||||
#TableOfContents ul li a{
|
||||
width: 100%;
|
||||
padding: .25em .375em;
|
||||
margin-left: -.375em;
|
||||
|
||||
}
|
||||
#TableOfContents ul li a:hover {
|
||||
background-color: #999;
|
||||
color: white;
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
.no-js .needs-js {
|
||||
opacity: 0
|
||||
}
|
||||
.js .needs-js {
|
||||
opacity: 1;
|
||||
transition: opacity .15s ease-in;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
@media print {
|
||||
#page-footer,
|
||||
body > footer,
|
||||
body > nav {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
#right-sidebar {
|
||||
scrollbar-width: none; /* hide scrollbar: Firefox */
|
||||
-ms-overflow-style: none; /* hide scrollbar: Internet Explorer 10+ */
|
||||
height: calc(100vh - 9rem);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#right-sidebar::-webkit-scrollbar { /* hide scrollbar: WebKit */
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
Make h6 elements behave like dt elements. Initially implemented to support
|
||||
linkable glossary entries.
|
||||
|
||||
Yes, it's a hack. That's why it's in the shame file.
|
||||
*/
|
||||
|
||||
h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
h6:first-of-type {
|
||||
margin-top: 3em;
|
||||
}
|
||||
|
||||
h6 ~ p {
|
||||
margin: 0.5em 0 2em 0;
|
||||
}
|
||||
|
||||
/* QR codes */
|
||||
img.qrcode {
|
||||
width: initial;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
.facebook,
|
||||
.twitter,
|
||||
.instagram,
|
||||
.youtube {
|
||||
fill: #bababa;
|
||||
}
|
||||
.facebook:hover {
|
||||
fill: #3b5998;
|
||||
}
|
||||
|
||||
.twitter {
|
||||
fill: #55acee;
|
||||
}
|
||||
|
||||
.twitter:hover {
|
||||
fill: #bababa;
|
||||
}
|
||||
|
||||
.instagram:hover {
|
||||
fill: #e95950;
|
||||
}
|
||||
|
||||
.youtube:hover {
|
||||
fill: #bb0000;
|
||||
}
|
||||
|
||||
.mstdn {
|
||||
display: inline-block;
|
||||
background-color: #282c37;
|
||||
color: #d9e1e8;
|
||||
text-decoration: none;
|
||||
padding: 4px 10px 4px 30px;
|
||||
border-radius: 4px;
|
||||
font-size: 16px;
|
||||
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2261.076954mm%22%20height%3D%2265.47831mm%22%20viewBox%3D%220%200%20216.4144%20232.00976%22%3E%3Cpath%20d%3D%22M211.80734%20139.0875c-3.18125%2016.36625-28.4925%2034.2775-57.5625%2037.74875-15.15875%201.80875-30.08375%203.47125-45.99875%202.74125-26.0275-1.1925-46.565-6.2125-46.565-6.2125%200%202.53375.15625%204.94625.46875%207.2025%203.38375%2025.68625%2025.47%2027.225%2046.39125%2027.9425%2021.11625.7225%2039.91875-5.20625%2039.91875-5.20625l.8675%2019.09s-14.77%207.93125-41.08125%209.39c-14.50875.7975-32.52375-.365-53.50625-5.91875C9.23234%20213.82%201.40609%20165.31125.20859%20116.09125c-.365-14.61375-.14-28.39375-.14-39.91875%200-50.33%2032.97625-65.0825%2032.97625-65.0825C49.67234%203.45375%2078.20359.2425%20107.86484%200h.72875c29.66125.2425%2058.21125%203.45375%2074.8375%2011.09%200%200%2032.975%2014.7525%2032.975%2065.0825%200%200%20.41375%2037.13375-4.59875%2062.915%22%20fill%3D%22%233088d4%22%2F%3E%3Cpath%20d%3D%22M177.50984%2080.077v60.94125h-24.14375v-59.15c0-12.46875-5.24625-18.7975-15.74-18.7975-11.6025%200-17.4175%207.5075-17.4175%2022.3525v32.37625H96.20734V85.42325c0-14.845-5.81625-22.3525-17.41875-22.3525-10.49375%200-15.74%206.32875-15.74%2018.7975v59.15H38.90484V80.077c0-12.455%203.17125-22.3525%209.54125-29.675%206.56875-7.3225%2015.17125-11.07625%2025.85-11.07625%2012.355%200%2021.71125%204.74875%2027.8975%2014.2475l6.01375%2010.08125%206.015-10.08125c6.185-9.49875%2015.54125-14.2475%2027.8975-14.2475%2010.6775%200%2019.28%203.75375%2025.85%2011.07625%206.36875%207.3225%209.54%2017.22%209.54%2029.675%22%20fill%3D%22%23fff%22%2F%3E%3C%2Fsvg%3E");
|
||||
background-size: 16px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: top 50% left 8px;
|
||||
transition: all 0.5s;
|
||||
}
|
||||
.mstdn:hover {
|
||||
background-color: #484c56;
|
||||
}
|
||||
|
||||
.mstdn > span {
|
||||
color: #9baec8;
|
||||
font-size: 12px;
|
||||
padding-left: 3px;
|
||||
}
|
||||
.mstdn > span:before {
|
||||
content: "@";
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
@media (min-width: 75em) {
|
||||
|
||||
[data-scrolldir="down"] .sticky {
|
||||
position: fixed;
|
||||
top:100px;
|
||||
right:0;
|
||||
}
|
||||
|
||||
[data-scrolldir="up"] .sticky {
|
||||
position: fixed;
|
||||
top:100px;
|
||||
right:0;
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
.fill-current { fill: currentColor; }
|
||||
@@ -1,34 +0,0 @@
|
||||
.tab-button{
|
||||
margin-bottom:1px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
color:#333;
|
||||
border-color:#ccc;
|
||||
outline: none;
|
||||
background-color:white;
|
||||
}
|
||||
.tab-pane code{
|
||||
background:#f1f2f2;
|
||||
border-radius:0;
|
||||
}
|
||||
.tab-pane .chroma{
|
||||
background:none;
|
||||
padding:0;
|
||||
}
|
||||
.tab-button.active{
|
||||
border-bottom-color:#f1f2f2;
|
||||
background-color: #f1f2f2;
|
||||
}
|
||||
.tab-content .tab-pane{
|
||||
display: none;
|
||||
}
|
||||
.tab-content .tab-pane.active{
|
||||
display: block;
|
||||
}
|
||||
/* Treatment of copy buttons inside a tab module */
|
||||
.tab-content .copy, .tab-content .copied{
|
||||
display: none;
|
||||
}
|
||||
.tab-content .tab-pane.active + .copy, .tab-content .tab-pane.active + .copied{
|
||||
display: block;
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*! TACHYONS v4.7.0 | http://tachyons.io */
|
||||
|
||||
/*
|
||||
* NOTE: The Tachyons folder is for backup/reference only. This file references the module
|
||||
* ________ ______
|
||||
* ___ __/_____ _________ /______ ______________________
|
||||
* __ / _ __ `/ ___/_ __ \_ / / / __ \_ __ \_ ___/
|
||||
* _ / / /_/ // /__ _ / / / /_/ // /_/ / / / /(__ )
|
||||
* /_/ \__,_/ \___/ /_/ /_/_\__, / \____//_/ /_//____/
|
||||
* /____/
|
||||
*
|
||||
* TABLE OF CONTENTS
|
||||
*
|
||||
* 1. External Library Includes
|
||||
* - Normalize.css | http://normalize.css.github.io
|
||||
* 2. Tachyons Modules
|
||||
* 3. Variables
|
||||
* - Media Queries
|
||||
* - Colors
|
||||
* 4. Debugging
|
||||
* - Debug all
|
||||
* - Debug children
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* External Library Includes */
|
||||
@import 'tachyons/src/_normalize';
|
||||
|
||||
|
||||
/* Modules */
|
||||
@import 'tachyons/src/_box-sizing';
|
||||
/*@import 'tachyons/src/_aspect-ratios';*/
|
||||
@import 'tachyons/src/_images';
|
||||
@import 'tachyons/src/_background-size';
|
||||
@import 'tachyons/src/_background-position';
|
||||
/*@import 'tachyons/src/_outlines';*/
|
||||
@import 'tachyons/src/_borders';
|
||||
@import 'tachyons/src/_border-colors';
|
||||
@import 'tachyons/src/_border-radius';
|
||||
@import 'tachyons/src/_border-style';
|
||||
@import 'tachyons/src/_border-widths';
|
||||
@import 'tachyons/src/_box-shadow';
|
||||
/*@import 'tachyons/src/_code';*/
|
||||
@import 'tachyons/src/_coordinates';
|
||||
@import 'tachyons/src/_clears';
|
||||
@import 'tachyons/src/_display';
|
||||
@import 'tachyons/src/_flexbox';
|
||||
@import 'tachyons/src/_floats';
|
||||
/*@import 'tachyons/src/_font-family';*/
|
||||
@import 'tachyons/src/_font-style';
|
||||
@import 'tachyons/src/_font-weight';
|
||||
@import 'tachyons/src/_forms';
|
||||
@import 'tachyons/src/_heights';
|
||||
@import 'tachyons/src/_letter-spacing';
|
||||
@import 'tachyons/src/_line-height';
|
||||
@import 'tachyons/src/_links';
|
||||
@import 'tachyons/src/_lists';
|
||||
@import 'tachyons/src/_max-widths';
|
||||
@import 'tachyons/src/_widths';
|
||||
@import 'tachyons/src/_overflow';
|
||||
@import 'tachyons/src/_position';
|
||||
@import 'tachyons/src/_opacity';
|
||||
/*@import 'tachyons/src/_rotations';*/
|
||||
@import 'tachyons/src/_skins';
|
||||
@import 'tachyons/src/_skins-pseudo';
|
||||
@import 'tachyons/src/_spacing';
|
||||
@import 'tachyons/src/_negative-margins';
|
||||
@import 'tachyons/src/_tables';
|
||||
@import 'tachyons/src/_text-decoration';
|
||||
@import 'tachyons/src/_text-align';
|
||||
@import 'tachyons/src/_text-transform';
|
||||
@import 'tachyons/src/_type-scale';
|
||||
@import 'tachyons/src/_typography';
|
||||
@import 'tachyons/src/_utilities';
|
||||
@import 'tachyons/src/_visibility';
|
||||
@import 'tachyons/src/_white-space';
|
||||
@import 'tachyons/src/_vertical-align';
|
||||
@import 'tachyons/src/_hovers';
|
||||
@import 'tachyons/src/_z-index';
|
||||
@import 'tachyons/src/_nested';
|
||||
/*@import 'tachyons/src/_styles';*/
|
||||
|
||||
/* Variables */
|
||||
/* Importing here will allow you to override any variables in the modules */
|
||||
@import 'tachyons/src/_colors';
|
||||
@import 'tachyons/src/_media-queries';
|
||||
|
||||
/* Debugging */
|
||||
/*@import 'tachyons/src/_debug-children';
|
||||
@import 'tachyons/src/_debug-grid';*/
|
||||
|
||||
/* Uncomment out the line below to help debug layout issues */
|
||||
/* @import 'tachyons/src/_debug'; */
|
||||
@@ -1,16 +0,0 @@
|
||||
:root {
|
||||
--primary-color: #0594CB;
|
||||
--primary-color-dark: #0A1922;
|
||||
--primary-color-light: #f9f9f9;
|
||||
--accent-color: #EBB951;
|
||||
--accent-color-light: #FF4088;
|
||||
--accent-color-dark: #33ba91;
|
||||
--text-color-primary: #373737;
|
||||
--text-on-primary-color: #fff;
|
||||
--text-color-secondary: #ccc;
|
||||
--text-color-disabled: #F7f7f7;
|
||||
--divider-color: #f6f6f6;
|
||||
--warn-color: red;
|
||||
|
||||
--blue: var(--primary-color);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*Base Styles*/
|
||||
@import '_tachyons';
|
||||
|
||||
/* purgecss start ignore */
|
||||
@import '_header-link';
|
||||
@import '_animation';
|
||||
@import '_documentation-styles';
|
||||
|
||||
@import 'docsearch.js/dist/cdn/docsearch.min';
|
||||
@import '_carousel';
|
||||
@import '_code';
|
||||
@import '_tabs';
|
||||
@import '_color-scheme';
|
||||
@import '_columns';
|
||||
@import '_content';
|
||||
@import '_content-tables';
|
||||
@import '_definition-lists';
|
||||
@import '_fluid-type';
|
||||
@import '_font-family';
|
||||
@import '_hugo-internal-template-styling';
|
||||
@import '_no-js';
|
||||
@import '_social-icons';
|
||||
@import '_stickyheader';
|
||||
@import '_right-sidebar';
|
||||
@import '_svg';
|
||||
@import '_chroma';
|
||||
@import '_variables';
|
||||
@import '_print';
|
||||
@import '_shame';
|
||||
|
||||
.nested-blockquote blockquote {
|
||||
border-left: 4px solid var(--primary-color);
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.mw-90 {
|
||||
max-width:90%;
|
||||
}
|
||||
/* purgecss end ignore */
|
||||
-1
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 575.8 178.3" viewBox="0 0 575.8 178.3"><path d="m148.6 78.9-24.7-13.6-20.8 12.7-.3 13-10.1-6.7-13.8 8.4c-.2-3.9-.4-8.6-.6-14.2l-14.2-9.5c3.9-2 8.4-4.3 13.5-7-.1 0 .1 1.4-2-46.5l-32-15.4-43.6 13.6 9.7 46.9 14.6 11.4-11.1 5.3 7.3 35.3 10.2 9.6-7.3 4.5 5.7 27.3 22.9 24.3c.1-.1 2.4-1.9 29.5-23.5l-.8-18.6 11.7 9.9c.2-.2 2.4-1.9 23.7-18.8l.8-13.7 8.8 6.1c.1-.2 2.1-1.7 19.3-15.3z"></path><path d="m128.1 93.5 20.5-14.6-24.7-13.6-20.8 12.7z" fill="#141414"></path><path d="m125.8 119.5 2.3-26-25-15.5-.5 25.4z" fill="#004b16"></path><path d="m92.6 146-.3-27-25.1-19.1 1.9 26.4z" fill="#004b16"></path><path d="m92.3 119 25.5-18.2-25.1-16.5-25.5 15.6z" fill="#141414"></path><path d="m52.1 178.2-4.1-27.6-24.6-24.1 5.7 27.4z" fill="#004b16"></path><path d="m48 150.6 32.4-23.1-25.1-20.4-31.9 19.4z" fill="#141414"></path><path d="m45.9 136.3-5.3-36.4-27.4-22.8 7.3 35.4z" fill="#004b16"></path><path d="m40.6 99.9 37.7-21.4-28.2-18.9-36.9 17.5z" fill="#141414"></path><path d="m38 82.5-7.3-49.9-30.7-19 9.7 46.9z" fill="#004b16"></path><path d="m30.7 32.6 44.9-17.2-32-15.4-43.6 13.6z" fill="#141414"></path><g fill="#1cb35c"><path d="m145.2 104.2c-19 15.1-19.4 15.4-19.3 15.4 2.4-27.2 2.2-26 2.3-26 21.8-15.5 20.4-14.6 20.5-14.6z"></path><path d="m116.2 127.2c-23.5 18.7-23.8 18.8-23.7 18.8-.2-28.2-.3-27-.2-27 27.1-19.4 25.4-18.2 25.5-18.2z"></path><path d="m81.6 154.7c-29.4 23.3-29.6 23.5-29.5 23.5-4.2-28.4-4.1-27.5-4-27.5 34.5-24.6 32.3-23.1 32.4-23.1z"></path><path d="m75.6 15.4c2.1 47.9 1.9 46.5 2 46.5-38.8 20.2-39.7 20.6-39.6 20.6-7.5-51-7.4-49.9-7.3-49.9z"></path><path d="m78.3 78.5c1.6 36.3 1.4 35.1 1.5 35.1-33.6 22.6-34 22.8-33.9 22.8-5.5-37.4-5.4-36.4-5.3-36.4z"></path></g><path d="m191.4 33.6 16.8-4c0 81.8-3.1 93.5 8 97.1-2.6 4.9-7.1 7.4-13.3 7.4-15.3 0-11.5-11.3-11.5-100.5z"></path><path d="m233.7 132.7v-58.4h-9.2v-13.8h26.3v72.2zm8.7-100.1c12.9 0 12.9 19.5 0 19.5s-12.9-19.5 0-19.5z"></path><path d="m316.8 132.7c0-43.6 1.1-49.6-3.5-55.2-5.8-6.9-20-5-26.1 3v52.2h-16.8v-72.2h12.1l3.1 6.7c9.1-10.8 30.4-10.9 40.6-.4 9.7 10 7.4 20.5 7.4 65.8z"></path><path d="m347.2 96.4c0-49.2 69.4-51.1 69.4 0-.1 50.7-69.4 50.8-69.4 0zm17.5 0c0 28.8 22.2 27.7 29.7 17.7 7-9.4 8.8-41.2-12.5-41.2-12.3 0-17.2 11.3-17.2 23.5z"></path><path d="m476.4 132.7c0-7.4 1.8-3.4-7.1-.4-10.2 3.5-25.1 2-34.1-7.9-11.1-12.3-12.6-39.5 1.3-54.6 11.4-12.3 28.5-13.1 39.9-7.4v-28.9l16.9-4v103.1zm0-54.9c-8.9-7.1-20.9-4.8-26.8 1.9-8.1 9.1-11.2 40.2 16.2 40.2 2.9 0 9-2.2 10.6-4.4z"></path><path d="m574.6 101.8h-51.6c1.2 22.3 29 21.4 38.1 12.2l6.5 12.9c-14 11.3-62.3 15-62.3-29.5.1-54.1 81.3-49 69.3 4.4zm-51-12.7h35.5c-1.2-10.6-7-15.8-17.5-15.8-9.7 0-15.6 5.2-18 15.8z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 2.7 KiB |
@@ -1,10 +0,0 @@
|
||||
require('typeface-muli');
|
||||
import styles from './css/main.css';
|
||||
import './js/clipboardjs.js';
|
||||
import './js/docsearch.js';
|
||||
import './js/lazysizes.js';
|
||||
import './js/menutoggle.js';
|
||||
import './js/scrolldir.js';
|
||||
import './js/smoothscroll.js';
|
||||
import './js/tabs.js';
|
||||
import './js/nojs.js';
|
||||
@@ -1,30 +0,0 @@
|
||||
var Clipboard = require('clipboard/dist/clipboard.js');
|
||||
new Clipboard('.copy', {
|
||||
target: function(trigger) {
|
||||
if(trigger.classList.contains('copy-toggle')){
|
||||
return trigger.previousElementSibling;
|
||||
}
|
||||
return trigger.nextElementSibling;
|
||||
}
|
||||
}).on('success', function(e) {
|
||||
successMessage(e.trigger, 'Copied!');
|
||||
e.clearSelection();
|
||||
}).on('error', function(e) {
|
||||
successMessage(e.trigger, fallbackMessage(e.action));
|
||||
});
|
||||
|
||||
function successMessage(elem, msg) {
|
||||
elem.setAttribute('class', 'copied bg-primary-color-dark f6 absolute top-0 right-0 lh-solid hover-bg-primary-color-dark bn white ph3 pv2');
|
||||
elem.setAttribute('aria-label', msg);
|
||||
}
|
||||
|
||||
function fallbackMessage(elem, action) {
|
||||
var actionMsg = '';
|
||||
var actionKey = (action === 'cut' ? 'X' : 'C');
|
||||
if (isMac) {
|
||||
actionMsg = 'Press ⌘-' + actionKey;
|
||||
} else {
|
||||
actionMsg = 'Press Ctrl-' + actionKey;
|
||||
}
|
||||
return actionMsg;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
var docsearch = require('docsearch.js/dist/cdn/docsearch.js');
|
||||
docsearch({
|
||||
appId: 'D1BPLZHGYQ',
|
||||
apiKey: '6df94e1e5d55d258c56f60d974d10314',
|
||||
indexName: 'hugodocs',
|
||||
inputSelector: '#search-input',
|
||||
debug: true, // Set debug to true if you want to inspect the dropdown
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
var lazysizes = require('lazysizes');
|
||||
// var lsnoscript = require('lazysizes/plugins/noscript/ls.noscript.js');
|
||||
var unveilhooks = require('lazysizes/plugins/unveilhooks/ls.unveilhooks.js');
|
||||
@@ -1,22 +0,0 @@
|
||||
import styles from './../css/main.css';
|
||||
import './clipboardjs.js'
|
||||
import './codeblocks.js'
|
||||
import './docsearch.js'
|
||||
import './lazysizes.js'
|
||||
import './menutoggle.js'
|
||||
import './scrolldir.js'
|
||||
import './smoothscroll.js'
|
||||
import './tabs.js'
|
||||
import './nojs.js'
|
||||
|
||||
// TO use jQuery, just call the modules you want
|
||||
// var $ = require('jquery/src/core');
|
||||
// require('jquery/src/core/init');
|
||||
// require('jquery/src/manipulation');
|
||||
|
||||
// OR, use all of them
|
||||
// var $ = require('jquery/src/jquery');
|
||||
|
||||
// And write your code
|
||||
// $('body').append('<p>Jquery is working</p>');
|
||||
//
|
||||
@@ -1,31 +0,0 @@
|
||||
// Grab any element that has the 'js-toggle' class and add an event listener for the toggleClass function
|
||||
var toggleBtns = document.getElementsByClassName('js-toggle')
|
||||
for (var i = 0; i < toggleBtns.length; i++) {
|
||||
toggleBtns[i].addEventListener('click', toggleClass, false)
|
||||
}
|
||||
|
||||
function toggleClass() {
|
||||
// Define the data target via the dataset "target" (e.g. data-target=".docsmenu")
|
||||
var content = this.dataset.target.split(' ')
|
||||
// Find any menu items that are open
|
||||
var mobileCurrentlyOpen = document.querySelector('.mobilemenu:not(.dn)')
|
||||
var desktopCurrentlyOpen = document.querySelector('.desktopmenu:not(.dn)')
|
||||
var desktopActive = document.querySelector('.desktopmenu:not(.dn)')
|
||||
|
||||
// Loop through the targets' divs
|
||||
for (var i = 0; i < content.length; i++) {
|
||||
var matches = document.querySelectorAll(content[i]);
|
||||
//for each, if the div has the 'dn' class (which is "display:none;"), remove it, otherwise, add that class
|
||||
[].forEach.call(matches, function(dom) {
|
||||
dom.classList.contains('dn') ?
|
||||
dom.classList.remove('dn') :
|
||||
dom.classList.add('dn');
|
||||
return false;
|
||||
});
|
||||
// close the currently open menu items
|
||||
if (mobileCurrentlyOpen) mobileCurrentlyOpen.classList.add('dn')
|
||||
if (desktopCurrentlyOpen) desktopCurrentlyOpen.classList.add('dn')
|
||||
if (desktopActive) desktopActive.classList.remove('db')
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/, 'js');
|
||||
@@ -1 +0,0 @@
|
||||
var scrollDir = require('scrolldir/dist/scrolldir.auto.min.js');
|
||||
@@ -1,80 +0,0 @@
|
||||
// query selector targets Hugo TOC
|
||||
(function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
// Feature Test
|
||||
if ('querySelector' in document && 'addEventListener' in window && Array.prototype.forEach) {
|
||||
|
||||
// Function to animate the scroll
|
||||
var smoothScroll = function(anchor, duration) {
|
||||
|
||||
// Calculate how far and how fast to scroll
|
||||
var startLocation = window.pageYOffset;
|
||||
var endLocation = anchor.offsetTop;
|
||||
var distance = endLocation - startLocation;
|
||||
var increments = distance / (duration / 16);
|
||||
var stopAnimation;
|
||||
|
||||
// Scroll the page by an increment, and check if it's time to stop
|
||||
var animateScroll = function() {
|
||||
window.scrollBy(0, increments);
|
||||
stopAnimation();
|
||||
};
|
||||
|
||||
// If scrolling down
|
||||
if (increments >= 0) {
|
||||
// Stop animation when you reach the anchor OR the bottom of the page
|
||||
stopAnimation = function() {
|
||||
var travelled = window.pageYOffset;
|
||||
if ((travelled >= (endLocation - increments)) || ((window.innerHeight + travelled) >= document.body.offsetHeight)) {
|
||||
clearInterval(runAnimation);
|
||||
}
|
||||
};
|
||||
}
|
||||
// If scrolling up
|
||||
else {
|
||||
// Stop animation when you reach the anchor OR the top of the page
|
||||
stopAnimation = function() {
|
||||
var travelled = window.pageYOffset;
|
||||
if (travelled <= (endLocation || 0)) {
|
||||
clearInterval(runAnimation);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Loop the animation function
|
||||
var runAnimation = setInterval(animateScroll, 16);
|
||||
|
||||
};
|
||||
|
||||
// Define smooth scroll links
|
||||
var scrollToggle = document.querySelectorAll('#TableOfContents ul li a');
|
||||
|
||||
// For each smooth scroll link
|
||||
[].forEach.call(scrollToggle, function(toggle) {
|
||||
|
||||
// When the smooth scroll link is clicked
|
||||
toggle.addEventListener('click', function(e) {
|
||||
|
||||
// Prevent the default link behavior
|
||||
e.preventDefault();
|
||||
|
||||
// Get anchor link and calculate distance from the top
|
||||
var dataID = toggle.getAttribute('href');
|
||||
var dataTarget = document.querySelector(dataID);
|
||||
var dataSpeed = toggle.getAttribute('data-speed');
|
||||
|
||||
// If the anchor exists
|
||||
if (dataTarget) {
|
||||
// Scroll to the anchor
|
||||
smoothScroll(dataTarget, dataSpeed || 500);
|
||||
}
|
||||
|
||||
}, false);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* Scripts which manages Code Toggle tabs.
|
||||
*/
|
||||
var i;
|
||||
// store tabs variable
|
||||
var allTabs = document.querySelectorAll("[data-toggle-tab]");
|
||||
var allPanes = document.querySelectorAll("[data-pane]");
|
||||
|
||||
function toggleTabs(event) {
|
||||
|
||||
if(event.target){
|
||||
event.preventDefault();
|
||||
var clickedTab = event.currentTarget;
|
||||
var targetKey = clickedTab.getAttribute("data-toggle-tab")
|
||||
}else {
|
||||
var targetKey = event
|
||||
}
|
||||
// We store the config language selected in users' localStorage
|
||||
if(window.localStorage){
|
||||
window.localStorage.setItem("configLangPref", targetKey)
|
||||
}
|
||||
var selectedTabs = document.querySelectorAll("[data-toggle-tab='" + targetKey + "']");
|
||||
var selectedPanes = document.querySelectorAll("[data-pane='" + targetKey + "']");
|
||||
|
||||
for (var i = 0; i < allTabs.length; i++) {
|
||||
allTabs[i].classList.remove("active");
|
||||
allPanes[i].classList.remove("active");
|
||||
}
|
||||
|
||||
for (var i = 0; i < selectedTabs.length; i++) {
|
||||
selectedTabs[i].classList.add("active");
|
||||
selectedPanes[i].classList.add("active");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < allTabs.length; i++) {
|
||||
allTabs[i].addEventListener("click", toggleTabs)
|
||||
}
|
||||
// Upon page load, if user has a preferred language in its localStorage, tabs are set to it.
|
||||
if(window.localStorage.getItem('configLangPref')) {
|
||||
toggleTabs(window.localStorage.getItem('configLangPref'))
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +0,0 @@
|
||||
|
||||
[module]
|
||||
[module.hugoVersion]
|
||||
min = "0.56.0"
|
||||
@@ -1,10 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<main class="cf pa5 pa4-l f4 tc center measure-wide lh-copy gray">
|
||||
<h1 class="f3 f2-ns">The page you're looking for doesn't exist. Perhaps you'd like to gopher something else? Sorry.</h1>
|
||||
<div class="h6">
|
||||
<img src="/images/gopher-hero.svg" alt="" class="h5">
|
||||
</div>
|
||||
|
||||
{{ .Content }}
|
||||
</main>
|
||||
{{ end }}
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
<pre class="mermaid">
|
||||
{{- .Inner | safeHTML }}
|
||||
</pre>
|
||||
{{ .Page.Store.Set "hasMermaid" true }}
|
||||
Generated
-5
@@ -1,5 +0,0 @@
|
||||
<h{{ .Level }} id="{{ .Anchor | safeURL }}">{{ .Text | safeHTML }}
|
||||
{{- if in (slice 2 3 4 6) .Level }}{{" " -}}
|
||||
<a class="header-link" href="#{{ .Anchor | safeURL }}"><svg class="fill-current o-60 hover-accent-color-light" height="22px" viewBox="0 0 24 24" width="22px" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg></a>
|
||||
{{- end -}}
|
||||
</h{{ .Level }}>
|
||||
-245
@@ -1,245 +0,0 @@
|
||||
{{- /* Last modified: 2024-04-26T13:54:00-07:00 */}}
|
||||
|
||||
{{- /*
|
||||
Copyright 2023 Veriphor LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
use this file except in compliance with the License. You may obtain a copy of
|
||||
the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations under
|
||||
the License.
|
||||
*/}}
|
||||
|
||||
{{- /*
|
||||
This render hook resolves internal destinations by looking for a matching:
|
||||
|
||||
1. Content page
|
||||
2. Page resource (a file in the current page bundle)
|
||||
3. Section resource (a file in the current section)
|
||||
4. Global resource (a file in the assets directory)
|
||||
|
||||
It skips the section resource lookup if the current page is a leaf bundle.
|
||||
|
||||
External destinations are not modified.
|
||||
|
||||
You must place global resources in the assets directory. If you have placed
|
||||
your resources in the static directory, and you are unable or unwilling to move
|
||||
them, you must mount the static directory to the assets directory by including
|
||||
both of these entries in your site configuration:
|
||||
|
||||
[[module.mounts]]
|
||||
source = 'assets'
|
||||
target = 'assets'
|
||||
|
||||
[[module.mounts]]
|
||||
source = 'static'
|
||||
target = 'assets'
|
||||
|
||||
By default, if this render hook is unable to resolve a destination, including a
|
||||
fragment if present, it passes the destination through without modification. To
|
||||
emit a warning or error, set the error level in your site configuration:
|
||||
|
||||
[params.render_hooks.link]
|
||||
errorLevel = 'warning' # ignore (default), warning, or error (fails the build)
|
||||
|
||||
When you set the error level to warning, and you are in a development
|
||||
environment, you can visually highlight broken internal links:
|
||||
|
||||
[params.render_hooks.link]
|
||||
errorLevel = 'warning' # ignore (default), warning, or error (fails the build)
|
||||
highlightBroken = true # true or false (default)
|
||||
|
||||
This will add a "broken" class to anchor elements with invalid src attributes.
|
||||
Add a rule to your CSS targeting the broken links:
|
||||
|
||||
a.broken {
|
||||
background: #ff0;
|
||||
border: 2px solid #f00;
|
||||
padding: 0.1em 0.2em;
|
||||
}
|
||||
|
||||
This render hook may be unable to resolve destinations created with the ref and
|
||||
relref shortcodes. Unless you set the error level to ignore you should not use
|
||||
either of these shortcodes in conjunction with this render hook.
|
||||
|
||||
@context {string} Destination The link destination.
|
||||
@context {page} Page A reference to the page containing the link.
|
||||
@context {string} PlainText The link description as plain text.
|
||||
@context {string} Text The link description.
|
||||
@context {string} Title The link title.
|
||||
|
||||
@returns {template.html}
|
||||
*/}}
|
||||
|
||||
{{- /* Initialize. */}}
|
||||
{{- $renderHookName := "link" }}
|
||||
|
||||
{{- /* Verify minimum required version. */}}
|
||||
{{- $minHugoVersion := "0.120.0" }}
|
||||
{{- if lt hugo.Version $minHugoVersion }}
|
||||
{{- errorf "The %q render hook requires Hugo v%s or later." $renderHookName $minHugoVersion }}
|
||||
{{- end }}
|
||||
|
||||
{{- /* Error level when unable to resolve destination: ignore, warning, or error. */}}
|
||||
{{- $errorLevel := or site.Params.render_hooks.link.errorLevel "ignore" | lower }}
|
||||
|
||||
{{- /* If true, adds "broken" class to broken links. Applicable in development environment when errorLevel is warning. */}}
|
||||
{{- $highlightBrokenLinks := or site.Params.render_hooks.link.highlightBroken false }}
|
||||
|
||||
{{- /* Validate error level. */}}
|
||||
{{- if not (in (slice "ignore" "warning" "error") $errorLevel) }}
|
||||
{{- errorf "The %q render hook is misconfigured. The errorLevel %q is invalid. Please check your site configuration." $renderHookName $errorLevel }}
|
||||
{{- end }}
|
||||
|
||||
{{- /* Determine content path for warning and error messages. */}}
|
||||
{{- $contentPath := .Page.String }}
|
||||
|
||||
{{- /* Parse destination. */}}
|
||||
{{- $u := urls.Parse .Destination }}
|
||||
|
||||
{{- /* Set common message. */}}
|
||||
{{- $msg := printf "The %q render hook was unable to resolve the destination %q in %s" $renderHookName $u.String $contentPath }}
|
||||
|
||||
{{- /* Set attributes for anchor element. */}}
|
||||
{{- $attrs := dict "href" $u.String }}
|
||||
{{- if $u.IsAbs }}
|
||||
{{- /* Destination is a remote resource. */}}
|
||||
{{- $attrs = merge $attrs (dict "rel" "external") }}
|
||||
{{- else }}
|
||||
{{- with $u.Path }}
|
||||
{{- with $p := or ($.PageInner.GetPage .) ($.PageInner.GetPage (strings.TrimRight "/" .)) }}
|
||||
{{- /* Destination is a page. */}}
|
||||
{{- $href := .RelPermalink }}
|
||||
{{- with $u.RawQuery }}
|
||||
{{- $href = printf "%s?%s" $href . }}
|
||||
{{- end }}
|
||||
{{- with $u.Fragment }}
|
||||
{{- $ctx := dict
|
||||
"contentPath" $contentPath
|
||||
"errorLevel" $errorLevel
|
||||
"page" $p
|
||||
"parsedURL" $u
|
||||
"renderHookName" $renderHookName
|
||||
}}
|
||||
{{- partial "inline/h-rh-l/validate-fragment.html" $ctx }}
|
||||
{{- $href = printf "%s#%s" $href . }}
|
||||
{{- end }}
|
||||
{{- $attrs = dict "href" $href }}
|
||||
{{- else }}
|
||||
{{- with $.PageInner.Resources.Get $u.Path }}
|
||||
{{- /* Destination is a page resource; drop query and fragment. */}}
|
||||
{{- $attrs = dict "href" .RelPermalink }}
|
||||
{{- else }}
|
||||
{{- with (and (ne $.Page.BundleType "leaf") ($.Page.CurrentSection.Resources.Get $u.Path)) }}
|
||||
{{- /* Destination is a section resource, and current page is not a leaf bundle. */}}
|
||||
{{- $attrs = dict "href" .RelPermalink }}
|
||||
{{- else }}
|
||||
{{- with resources.Get $u.Path }}
|
||||
{{- /* Destination is a global resource; drop query and fragment. */}}
|
||||
{{- $attrs = dict "href" .RelPermalink }}
|
||||
{{- else }}
|
||||
{{- if eq $errorLevel "warning" }}
|
||||
{{- warnf $msg }}
|
||||
{{- if and $highlightBrokenLinks hugo.IsDevelopment }}
|
||||
{{- $attrs = merge $attrs (dict "class" "broken") }}
|
||||
{{- end }}
|
||||
{{- else if eq $errorLevel "error" }}
|
||||
{{- errorf $msg }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- with $u.Fragment }}
|
||||
{{- /* Destination is on the same page; prepend relative permalink. */}}
|
||||
{{- $ctx := dict
|
||||
"contentPath" $contentPath
|
||||
"errorLevel" $errorLevel
|
||||
"page" $.Page
|
||||
"parsedURL" $u
|
||||
"renderHookName" $renderHookName
|
||||
}}
|
||||
{{- partial "inline/h-rh-l/validate-fragment.html" $ctx }}
|
||||
{{- $attrs = dict "href" (printf "%s#%s" $.Page.RelPermalink .) }}
|
||||
{{- else }}
|
||||
{{- if eq $errorLevel "warning" }}
|
||||
{{- warnf $msg }}
|
||||
{{- if and $highlightBrokenLinks hugo.IsDevelopment }}
|
||||
{{- $attrs = merge $attrs (dict "class" "broken") }}
|
||||
{{- end }}
|
||||
{{- else if eq $errorLevel "error" }}
|
||||
{{- errorf $msg }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $attrs = merge $attrs (dict "title" (.Title | transform.HTMLEscape)) }}
|
||||
|
||||
{{- /* Render anchor element. */ -}}
|
||||
<a
|
||||
{{- range $k, $v := $attrs }}
|
||||
{{- if $v }}
|
||||
{{- printf " %s=%q" $k $v | safeHTMLAttr }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
>{{ .Text | safeHTML }}</a>
|
||||
|
||||
{{- define "partials/inline/h-rh-l/validate-fragment.html" }}
|
||||
{{- /*
|
||||
Validates the fragment portion of a link destination.
|
||||
|
||||
@context {string} contentPath The page containing the link.
|
||||
@context {string} errorLevel The error level when unable to resolve destination; ignore (default), warning, or error.
|
||||
@context {page} page The page corresponding to the link destination
|
||||
@context {struct} parsedURL The link destination parsed by urls.Parse.
|
||||
@context {string} renderHookName The name of the render hook.
|
||||
*/}}
|
||||
|
||||
{{- /* Initialize. */}}
|
||||
{{- $contentPath := .contentPath }}
|
||||
{{- $errorLevel := .errorLevel }}
|
||||
{{- $p := .page }}
|
||||
{{- $u := .parsedURL }}
|
||||
{{- $renderHookName := .renderHookName }}
|
||||
|
||||
{{- /* Validate. */}}
|
||||
{{- with $u.Fragment }}
|
||||
{{- if $p.Fragments.Identifiers.Contains . }}
|
||||
{{- if gt ($p.Fragments.Identifiers.Count .) 1 }}
|
||||
{{- $msg := printf "The %q render hook detected duplicate heading IDs %q in %s" $renderHookName . $contentPath }}
|
||||
{{- if eq $errorLevel "warning" }}
|
||||
{{- warnf $msg }}
|
||||
{{- else if eq $errorLevel "error" }}
|
||||
{{- errorf $msg }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- /* Determine target path for warning and error message. */}}
|
||||
{{- $targetPath := "" }}
|
||||
{{- with $p.File }}
|
||||
{{- $targetPath = .Path }}
|
||||
{{- else }}
|
||||
{{- $targetPath = .Path }}
|
||||
{{- end }}
|
||||
{{- /* Set common message. */}}
|
||||
{{- $msg := printf "The %q render hook was unable to find heading ID %q in %s. See %s" $renderHookName . $targetPath $contentPath }}
|
||||
{{- if eq $targetPath $contentPath }}
|
||||
{{- $msg = printf "The %q render hook was unable to find heading ID %q in %s" $renderHookName . $targetPath }}
|
||||
{{- end }}
|
||||
{{- /* Throw warning or error. */}}
|
||||
{{- if eq $errorLevel "warning" }}
|
||||
{{- warnf $msg }}
|
||||
{{- else if eq $errorLevel "error" }}
|
||||
{{- errorf $msg }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- end -}}
|
||||
-122
@@ -1,122 +0,0 @@
|
||||
<!doctype html>
|
||||
<html
|
||||
class="no-js"
|
||||
lang="{{ with $.Site.LanguageCode }}
|
||||
{{ . }}
|
||||
{{ else }}
|
||||
en-us
|
||||
{{ end }}
|
||||
">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
{{/* https://www.zachleat.com/web/preload/ */}}
|
||||
<link
|
||||
rel="preload"
|
||||
href="{{ "fonts/muli-latin-200.woff2" | absURL }}"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin />
|
||||
<link
|
||||
rel="preload"
|
||||
href="{{ "fonts/muli-latin-400.woff2" | absURL }}"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin />
|
||||
<link
|
||||
rel="preload"
|
||||
href="{{ "fonts/muli-latin-800.woff2" | absURL }}"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin />
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
{{/* NOTE: the Site's title, and if there is a page title, that is set too */}}
|
||||
<title>
|
||||
{{ block "title" . }}
|
||||
{{ with .Title }}{{ . }} | {{ end }}{{ .Site.Title }}
|
||||
{{ end }}
|
||||
|
||||
</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width,minimum-scale=1" />
|
||||
{{ hugo.Generator }}
|
||||
|
||||
{{ if hugo.IsProduction }}
|
||||
<meta name="robots" content="index, follow" />
|
||||
{{ else }}
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
{{ end }}
|
||||
|
||||
{{ range .AlternativeOutputFormats -}}
|
||||
<link
|
||||
rel="{{ .Rel }}"
|
||||
type="{{ .MediaType.Type }}"
|
||||
href="{{ .Permalink | safeURL }}" />
|
||||
{{ end -}}
|
||||
|
||||
{{ $isDev := eq hugo.Environment "development" }}
|
||||
{{ $stylesheet := resources.Get "output/css/app.css" }}
|
||||
{{ if not $isDev }}
|
||||
{{ $stylesheet = $stylesheet | minify | fingerprint }}
|
||||
{{ end }}
|
||||
{{ with $stylesheet }}
|
||||
{{ if $isDev }}
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="{{ .RelPermalink }}"
|
||||
crossorigin="anonymous" />
|
||||
{{ else }}
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="{{ .RelPermalink }}"
|
||||
integrity="{{ .Data.Integrity }}"
|
||||
crossorigin="anonymous" />
|
||||
{{ end }}
|
||||
{{ $.Scratch.Set "stylesheet" . }}
|
||||
{{ end }}
|
||||
|
||||
|
||||
<meta
|
||||
name="description"
|
||||
content="{{ with .Description }}
|
||||
{{ . }}
|
||||
{{ else }}
|
||||
{{ with .Site.Params.description }}{{ . }}{{ end }}
|
||||
{{ end }}
|
||||
" />
|
||||
|
||||
{{ block "scripts" . }}
|
||||
{{- partial "site-scripts.html" . -}}
|
||||
{{ end }}
|
||||
{{ partial "site-manifest.html" . }}
|
||||
{{- partial "head-additions.html" . -}}
|
||||
{{- partial "opengraph/opengraph.html" . -}}
|
||||
{{- template "_internal/schema.html" . -}}
|
||||
{{- partial "opengraph/twitter_cards.html" . -}}
|
||||
|
||||
{{ if hugo.IsProduction }}
|
||||
{{ partial "gtag.html" . }}
|
||||
{{ end }}
|
||||
|
||||
{{ $hasMath := .Param "math" }}
|
||||
{{ if $hasMath }}
|
||||
{{ partialCached "math.html" . }}
|
||||
{{ end }}
|
||||
|
||||
</head>
|
||||
|
||||
<body
|
||||
class="ma0 sans-serif bg-primary-color-light{{ with getenv "HUGO_ENV" }} {{ . }}{{ end }}">
|
||||
{{ partial "hooks/after-body-start.html" . }}
|
||||
{{ block "nav" . }}{{ partial "site-nav.html" . }}{{ end }}
|
||||
{{ block "header" . }}{{ end }}
|
||||
<main role="main" class="content-with-sidebar min-vh-100 pb7 pb0-ns">
|
||||
{{ block "main" . }}{{ end }}
|
||||
</main>
|
||||
|
||||
{{ block "footer" . }}{{ partialCached "site-footer.html" . }}{{ end }}
|
||||
|
||||
{{ partial "hooks/before-body-end.html" . }}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
{{ define "main" }}
|
||||
{{ $section_to_display := (.Site.Taxonomies.categories.fundamentals).Pages | lang.Merge (.Sites.Default.Taxonomies.categories.fundamentals).Pages }}
|
||||
{{ partial "pagelayout.html" (dict "context" . "section_to_display" $section_to_display ) }}
|
||||
{{ end }}
|
||||
@@ -1,5 +0,0 @@
|
||||
{{ define "main" }}
|
||||
{{ $paginator := .Paginate (.Pages | lang.Merge (where .Sites.Default.RegularPages "Section" .Section)) }}
|
||||
{{ $section_to_display := .Sections | default $paginator.Pages }}
|
||||
{{ partial "pagelayout.html" (dict "context" . "section_to_display" $section_to_display ) }}
|
||||
{{ end }}
|
||||
@@ -1,48 +0,0 @@
|
||||
<header class="flex-none w-100">
|
||||
{{ if in (slice "functions" "methods") .Type }}
|
||||
{{ with .FirstSection }}
|
||||
<a href="{{ .RelPermalink }}" class="f6 fw8 mb0 link mid-gray dim mr3">
|
||||
{{ humanize .Title | upper }}
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ with .CurrentSection }}
|
||||
<a href="{{ .RelPermalink }}" class="f6 fw8 mb0 link mid-gray dim mr3">
|
||||
{{ humanize .Title | upper }}
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
{{ range .Params.categories }}
|
||||
<a href="{{ "/categories/" | relLangURL }}{{ . | urlize }}" class="f6 fw8 mb0 link mid-gray dim mr3">
|
||||
{{ humanize . | upper }}
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<h1 class="lh-title mb3 mv0 pt3 primary-color-dark">
|
||||
{{ .Title }}
|
||||
</h1>
|
||||
</header>
|
||||
|
||||
<aside class="bt bw1 pt3 mt2 mid-gray b--mid-gray fn w-100">
|
||||
{{ with .Params.description }}
|
||||
<div class="mb4 f4 fw4 lh-copy">
|
||||
{{ . | markdownify }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
<!--
|
||||
NOTE: Removed to test builds without it.
|
||||
partial "components/author-github-data" (dict "context" . "size" "110") -->
|
||||
</aside>
|
||||
|
||||
{{ with .Params.featured_image_path }}
|
||||
<img src="{{ . }}" alt="Featured Image for {{ $.Title }}" class="mw-100">
|
||||
{{ end }}
|
||||
|
||||
<div class="prose" id="prose">
|
||||
<div class="mb4">
|
||||
{{- partial "docs/functions-signatures.html" . -}}
|
||||
{{- partial "docs/functions-return-type.html" . -}}
|
||||
{{- partial "docs/functions-aliases.html" . -}}
|
||||
</div>
|
||||
{{ .Content }}
|
||||
</div>
|
||||
@@ -1,29 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<article class="w-100 ph4 pb5 pb6-ns pt1 pt5-ns">
|
||||
<div class="flex-l">
|
||||
|
||||
<div class="order-0 w-20 dn db-l">
|
||||
{{ partial "nav-links-docs.html" . }}
|
||||
</div>
|
||||
<div class="order-1 flex-grow-1 ph0 ph5-ns mt0-ns mid-gray nested-copy-line-height no-underline nested-links nested-img nested-copy-seperator nested-blockquote">
|
||||
<div style="max-width: 40rem;" class="documentation-copy">
|
||||
<div id="readout" class="fixed right-0 bottom-0"></div>
|
||||
{{ .Render "page" }}
|
||||
{{ partial "related.html" . }}
|
||||
</div>
|
||||
</div>
|
||||
<div id="right-sidebar" class="order-2 w-20 dn db-l sticky pt2">
|
||||
{{ partial "right-sidebar.html" . }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<div id="page-footer" class="w-100 bg-light-gray">
|
||||
<div class="mw7 pa4 center nested-lh-copy lh-copy">
|
||||
{{ partial "docs/page-meta-data.html" . }}
|
||||
{{ partial "page-edit.html" . }}
|
||||
{{ partial "tags.html" . }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
{{ define "main" }}
|
||||
{{ $section_to_display := .Pages }}
|
||||
{{ partial "pagelayout.html" (dict "context" . "section_to_display" $section_to_display ) }}
|
||||
{{ end }}
|
||||
@@ -1,48 +0,0 @@
|
||||
{{ define "main" }}
|
||||
{{ $section_to_display := .Pages }}
|
||||
<div class="w-100 ph4 pb5 pb6-ns pt1 pt3-ns">
|
||||
|
||||
<div class="flex">
|
||||
<div class="dn db-l w-20">
|
||||
{{ partial "nav-links-docs.html" . }}
|
||||
</div>
|
||||
|
||||
<div class="w-100 w-80-l ph0 ph4-l">
|
||||
<article class="w-100 nested-copy-line-height nested-links nested-img">
|
||||
<h1 class="primary-color-dark f2">
|
||||
{{ .Title }}
|
||||
</h1>
|
||||
</article>
|
||||
<div class="pa3 pa4-ns w-100 v-top column-count-3-l column-gap-1-l">
|
||||
{{ range $key, $value := .Data.Terms }}
|
||||
<div class="break-inside-avoid-l nested-copy-line-height mb5">
|
||||
<h2 class="f3">
|
||||
<a href="{{ "/" | relLangURL }}{{ $.Data.Plural | urlize }}/{{ $key | urlize }}" class="link black hover-blue">
|
||||
{{ $key }} <span class="f6 gray"> ↗</span>
|
||||
</a>
|
||||
</h2>
|
||||
{{ range $value.Pages }}
|
||||
<h3>
|
||||
<a href="{{ .Permalink }}" class="link blue">
|
||||
{{ .Title }}
|
||||
</a>
|
||||
</h3>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
{{ end }}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
{{ end }}
|
||||
@@ -1,27 +0,0 @@
|
||||
{{ define "header" }}
|
||||
{{ partial "hero.html" . }}
|
||||
{{ partial "boxes-small-news.html" . }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "main" }}
|
||||
<section class="w-100 ph4 ph5-ns pv4">
|
||||
{{- partial "home-page-sections/features-icons.html" . -}}
|
||||
</section>
|
||||
|
||||
{{ partial "home-page-sections/sponsors.html" (dict "cx" . "gtag" "home" ) }}
|
||||
|
||||
{{- partial "home-page-sections/features-single.html" . -}}
|
||||
|
||||
{{/*- partial "home-page-sections/showcase.html" . -*/}}
|
||||
|
||||
<section class="w-100 ph4 ph5-ns pv4 pv6-ns mid-gray bg-white bb bt b--light-gray">
|
||||
{{- partial "home-page-sections/installation.html" . -}}
|
||||
</section>
|
||||
|
||||
<section class="w-100 ph4 ph5-ns pv4 pv6-ns mid-gray bg-accent-color-dark">
|
||||
{{- partial "home-page-sections/tweets.html" . -}}
|
||||
</section>
|
||||
<section class="w-100 ph4 ph5-ns pt4 pb5 mid-gray bg-primary-color-light bb bt b--light-gray ">
|
||||
{{- partial "home-page-sections/open-source-involvement.html" . -}}
|
||||
</section>
|
||||
{{ end }}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user