mirror of
https://github.com/gohugoio/hugo.git
synced 2024-05-13 04:52:48 +00:00
Compare commits
11 commits
7a7251de12
...
b6b8696ebc
Author | SHA1 | Date | |
---|---|---|---|
b6b8696ebc | |||
4e483f5d4a | |||
06d248910c | |||
004b694390 | |||
da6112fc65 | |||
faf9fedc3d | |||
11aa893198 | |||
d88cb5269a | |||
68c5ad638c | |||
0c188fda24 | |||
c91c64a1aa |
16
cache/dynacache/dynacache.go
vendored
16
cache/dynacache/dynacache.go
vendored
|
@ -140,16 +140,25 @@ func (c *Cache) DrainEvictedIdentities() []identity.Identity {
|
|||
}
|
||||
|
||||
// ClearMatching clears all partition for which the predicate returns true.
|
||||
func (c *Cache) ClearMatching(predicate func(k, v any) bool) {
|
||||
func (c *Cache) ClearMatching(predicatePartition func(k string, p PartitionManager) bool, predicateValue func(k, v any) bool) {
|
||||
if predicatePartition == nil {
|
||||
predicatePartition = func(k string, p PartitionManager) bool { return true }
|
||||
}
|
||||
if predicateValue == nil {
|
||||
panic("nil predicateValue")
|
||||
}
|
||||
g := rungroup.Run[PartitionManager](context.Background(), rungroup.Config[PartitionManager]{
|
||||
NumWorkers: len(c.partitions),
|
||||
Handle: func(ctx context.Context, partition PartitionManager) error {
|
||||
partition.clearMatching(predicate)
|
||||
partition.clearMatching(predicateValue)
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
for _, p := range c.partitions {
|
||||
for k, p := range c.partitions {
|
||||
if !predicatePartition(k, p) {
|
||||
continue
|
||||
}
|
||||
g.Enqueue(p)
|
||||
}
|
||||
|
||||
|
@ -356,6 +365,7 @@ func GetOrCreatePartition[K comparable, V any](c *Cache, name string, opts Optio
|
|||
trace: c.opts.Log.Logger().WithLevel(logg.LevelTrace).WithField("partition", name),
|
||||
opts: opts,
|
||||
}
|
||||
|
||||
c.partitions[name] = partition
|
||||
|
||||
return partition
|
||||
|
|
2
cache/dynacache/dynacache_test.go
vendored
2
cache/dynacache/dynacache_test.go
vendored
|
@ -156,7 +156,7 @@ func TestClear(t *testing.T) {
|
|||
|
||||
cache = newTestCache(t)
|
||||
|
||||
cache.ClearMatching(func(k, v any) bool {
|
||||
cache.ClearMatching(nil, func(k, v any) bool {
|
||||
return k.(string) == "clearOnRebuild"
|
||||
})
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ type rootCommand struct {
|
|||
verbose bool
|
||||
debug bool
|
||||
quiet bool
|
||||
devMode bool // Hidden flag.
|
||||
|
||||
renderToMemory bool
|
||||
|
||||
|
@ -423,29 +424,33 @@ func (r *rootCommand) PreRun(cd, runner *simplecobra.Commandeer) error {
|
|||
func (r *rootCommand) createLogger(running bool) (loggers.Logger, error) {
|
||||
level := logg.LevelWarn
|
||||
|
||||
if r.logLevel != "" {
|
||||
switch strings.ToLower(r.logLevel) {
|
||||
case "debug":
|
||||
level = logg.LevelDebug
|
||||
case "info":
|
||||
level = logg.LevelInfo
|
||||
case "warn", "warning":
|
||||
level = logg.LevelWarn
|
||||
case "error":
|
||||
level = logg.LevelError
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid log level: %q, must be one of debug, warn, info or error", r.logLevel)
|
||||
}
|
||||
if r.devMode {
|
||||
level = logg.LevelTrace
|
||||
} else {
|
||||
if r.verbose {
|
||||
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
|
||||
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
|
||||
level = logg.LevelInfo
|
||||
}
|
||||
if r.logLevel != "" {
|
||||
switch strings.ToLower(r.logLevel) {
|
||||
case "debug":
|
||||
level = logg.LevelDebug
|
||||
case "info":
|
||||
level = logg.LevelInfo
|
||||
case "warn", "warning":
|
||||
level = logg.LevelWarn
|
||||
case "error":
|
||||
level = logg.LevelError
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid log level: %q, must be one of debug, warn, info or error", r.logLevel)
|
||||
}
|
||||
} else {
|
||||
if r.verbose {
|
||||
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
|
||||
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
|
||||
level = logg.LevelInfo
|
||||
}
|
||||
|
||||
if r.debug {
|
||||
hugo.Deprecate("--debug", "use --logLevel debug", "v0.114.0")
|
||||
level = logg.LevelDebug
|
||||
if r.debug {
|
||||
hugo.Deprecate("--debug", "use --logLevel debug", "v0.114.0")
|
||||
level = logg.LevelDebug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -505,10 +510,13 @@ Complete documentation is available at https://gohugo.io/.`
|
|||
|
||||
cmd.PersistentFlags().BoolVarP(&r.verbose, "verbose", "v", false, "verbose output")
|
||||
cmd.PersistentFlags().BoolVarP(&r.debug, "debug", "", false, "debug output")
|
||||
cmd.PersistentFlags().BoolVarP(&r.devMode, "devMode", "", false, "only used for internal testing, flag hidden.")
|
||||
cmd.PersistentFlags().StringVar(&r.logLevel, "logLevel", "", "log level (debug|info|warn|error)")
|
||||
_ = cmd.RegisterFlagCompletionFunc("logLevel", cobra.FixedCompletions([]string{"debug", "info", "warn", "error"}, cobra.ShellCompDirectiveNoFileComp))
|
||||
cmd.Flags().BoolVarP(&r.buildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed")
|
||||
|
||||
cmd.PersistentFlags().MarkHidden("devMode")
|
||||
|
||||
// Configure local flags
|
||||
applyLocalFlagsBuild(cmd, r)
|
||||
|
||||
|
|
|
@ -45,9 +45,10 @@ func newGenCommand() *genCommand {
|
|||
genmandir string
|
||||
|
||||
// Chroma flags.
|
||||
style string
|
||||
highlightStyle string
|
||||
linesStyle string
|
||||
style string
|
||||
highlightStyle string
|
||||
lineNumbersInlineStyle string
|
||||
lineNumbersTableStyle string
|
||||
)
|
||||
|
||||
newChromaStyles := func() simplecobra.Commander {
|
||||
|
@ -63,8 +64,11 @@ See https://xyproto.github.io/splash/docs/all.html for a preview of the availabl
|
|||
if highlightStyle != "" {
|
||||
builder.Add(chroma.LineHighlight, highlightStyle)
|
||||
}
|
||||
if linesStyle != "" {
|
||||
builder.Add(chroma.LineNumbers, linesStyle)
|
||||
if lineNumbersInlineStyle != "" {
|
||||
builder.Add(chroma.LineNumbers, lineNumbersInlineStyle)
|
||||
}
|
||||
if lineNumbersTableStyle != "" {
|
||||
builder.Add(chroma.LineNumbersTable, lineNumbersTableStyle)
|
||||
}
|
||||
style, err := builder.Build()
|
||||
if err != nil {
|
||||
|
@ -78,10 +82,12 @@ See https://xyproto.github.io/splash/docs/all.html for a preview of the availabl
|
|||
cmd.ValidArgsFunction = cobra.NoFileCompletions
|
||||
cmd.PersistentFlags().StringVar(&style, "style", "friendly", "highlighter style (see https://xyproto.github.io/splash/docs/)")
|
||||
_ = cmd.RegisterFlagCompletionFunc("style", cobra.NoFileCompletions)
|
||||
cmd.PersistentFlags().StringVar(&highlightStyle, "highlightStyle", "", "style used for highlighting lines (see https://github.com/alecthomas/chroma)")
|
||||
cmd.PersistentFlags().StringVar(&highlightStyle, "highlightStyle", "", `foreground and background colors for highlighted lines, e.g. --highlightStyle "#fff000 bg:#000fff"`)
|
||||
_ = cmd.RegisterFlagCompletionFunc("highlightStyle", cobra.NoFileCompletions)
|
||||
cmd.PersistentFlags().StringVar(&linesStyle, "linesStyle", "", "style used for line numbers (see https://github.com/alecthomas/chroma)")
|
||||
_ = cmd.RegisterFlagCompletionFunc("linesStyle", cobra.NoFileCompletions)
|
||||
cmd.PersistentFlags().StringVar(&lineNumbersInlineStyle, "lineNumbersInlineStyle", "", `foreground and background colors for inline line numbers, e.g. --lineNumbersInlineStyle "#fff000 bg:#000fff"`)
|
||||
_ = cmd.RegisterFlagCompletionFunc("lineNumbersInlineStyle", cobra.NoFileCompletions)
|
||||
cmd.PersistentFlags().StringVar(&lineNumbersTableStyle, "lineNumbersTableStyle", "", `foreground and background colors for table line numbers, e.g. --lineNumbersTableStyle "#fff000 bg:#000fff"`)
|
||||
_ = cmd.RegisterFlagCompletionFunc("lineNumbersTableStyle", cobra.NoFileCompletions)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ package hugo
|
|||
// This should be the only one.
|
||||
var CurrentVersion = Version{
|
||||
Major: 0,
|
||||
Minor: 126,
|
||||
PatchLevel: 0,
|
||||
Suffix: "-DEV",
|
||||
Minor: 125,
|
||||
PatchLevel: 2,
|
||||
Suffix: "",
|
||||
}
|
||||
|
|
|
@ -20,10 +20,11 @@ hugo gen chromastyles [flags] [args]
|
|||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for chromastyles
|
||||
--highlightStyle string style used for highlighting lines (see https://github.com/alecthomas/chroma)
|
||||
--linesStyle string style used for line numbers (see https://github.com/alecthomas/chroma)
|
||||
--style string highlighter style (see https://xyproto.github.io/splash/docs/) (default "friendly")
|
||||
-h, --help help for chromastyles
|
||||
--highlightStyle string foreground and background colors for highlighted lines, e.g. --highlightStyle "#fff000 bg:#000fff"
|
||||
--lineNumbersInlineStyle string foreground and background colors for inline line numbers, e.g. --lineNumbersInlineStyle "#fff000 bg:#000fff"
|
||||
--lineNumbersTableStyle string foreground and background colors for table line numbers, e.g. --lineNumbersTableStyle "#fff000 bg:#000fff"
|
||||
--style string highlighter style (see https://xyproto.github.io/splash/docs/) (default "friendly")
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
|
|
@ -43,7 +43,7 @@ Hugo passes reasonable default arguments to these external helpers by default:
|
|||
|
||||
- `asciidoctor`: `--no-header-footer -`
|
||||
- `rst2html`: `--leave-comments --initial-header-level=2`
|
||||
- `pandoc`: `--mathjax`
|
||||
- `pandoc`: `--mathjax` and, for pandoc >= 2.11, `--citeproc`
|
||||
|
||||
{{% note %}}
|
||||
Because additional formats are external commands, generation performance will rely heavily on the performance of the external tool you are using. As this feature is still in its infancy, feedback is welcome.
|
||||
|
@ -63,7 +63,59 @@ Some Asciidoctor parameters can be customized in Hugo. See [details].
|
|||
|
||||
[details]: /getting-started/configuration-markup/#asciidoc
|
||||
|
||||
## Learn markdown
|
||||
### External Helper Pandoc
|
||||
|
||||
[Pandoc](https://pandoc.org) is a universal document converter and can be used to convert markdown files.
|
||||
In Hugo, Pandoc can be used for LaTeX-style math (the `--mathjax` command line option is provided):
|
||||
|
||||
```
|
||||
---
|
||||
title: Math document
|
||||
---
|
||||
|
||||
Some inline math: $a^2 + b^2 = c^2$.
|
||||
```
|
||||
|
||||
This will render in your HTML as:
|
||||
|
||||
```
|
||||
<p>Some inline math: <span class="math inline">\(a^2 + b^2 = c^2\)</span></p>
|
||||
```
|
||||
You will have to [add MathJax](https://www.mathjax.org/#gettingstarted) to your template to properly render the math.
|
||||
|
||||
For **Pandoc >= 2.11**, you can use [citations](https://pandoc.org/MANUAL.html#extension-citations).
|
||||
One way is to employ [BibTeX files](https://en.wikibooks.org/wiki/LaTeX/Bibliography_Management#BibTeX) to cite:
|
||||
|
||||
```
|
||||
---
|
||||
title: Citation document
|
||||
---
|
||||
---
|
||||
bibliography: assets/bibliography.bib
|
||||
...
|
||||
This is a citation: @Doe2022
|
||||
```
|
||||
|
||||
Note that Hugo will **not** pass its metadata YAML block to Pandoc; however, it will pass the **second** meta data block, denoted with `---` and `...` to Pandoc.
|
||||
Thus, all Pandoc settings should go there.
|
||||
|
||||
You can also add all elements from a bibliography file (without citing them explicitly) using:
|
||||
|
||||
```
|
||||
---
|
||||
title: My Publications
|
||||
---
|
||||
---
|
||||
bibliography: assets/bibliography.bib
|
||||
nocite: |
|
||||
@*
|
||||
...
|
||||
```
|
||||
|
||||
It is also possible to provide a custom [CSL style](https://citationstyles.org/authors/) by passing `csl: path-to-style.csl` as a Pandoc option.
|
||||
|
||||
|
||||
## Learn Markdown
|
||||
|
||||
Markdown syntax is simple enough to learn in a single sitting. The following are excellent resources to get you up and running:
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ package hqt
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
|
@ -38,6 +39,11 @@ var IsSameType qt.Checker = &typeChecker{
|
|||
argNames: []string{"got", "want"},
|
||||
}
|
||||
|
||||
// IsSameFloat64 asserts that two float64 values are equal within a small delta.
|
||||
var IsSameFloat64 = qt.CmpEquals(cmp.Comparer(func(a, b float64) bool {
|
||||
return math.Abs(a-b) < 0.0001
|
||||
}))
|
||||
|
||||
type argNames []string
|
||||
|
||||
func (a argNames) ArgNames() []string {
|
||||
|
|
|
@ -1084,7 +1084,7 @@ func (h *HugoSites) resolveAndClearStateForIdentities(
|
|||
return b
|
||||
}
|
||||
|
||||
h.MemCache.ClearMatching(shouldDelete)
|
||||
h.MemCache.ClearMatching(nil, shouldDelete)
|
||||
|
||||
return ll, nil
|
||||
}); err != nil {
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/bep/logg"
|
||||
|
@ -46,6 +47,7 @@ import (
|
|||
"github.com/gohugoio/hugo/resources/page"
|
||||
"github.com/gohugoio/hugo/resources/page/siteidentities"
|
||||
"github.com/gohugoio/hugo/resources/postpub"
|
||||
"github.com/gohugoio/hugo/resources/resource"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
|
||||
|
@ -758,15 +760,45 @@ func (h *HugoSites) processPartial(ctx context.Context, l logg.LevelLogger, conf
|
|||
}
|
||||
}
|
||||
case files.ComponentFolderAssets:
|
||||
logger.Println("Asset changed", pathInfo.Path())
|
||||
p := pathInfo.Path()
|
||||
logger.Println("Asset changed", p)
|
||||
|
||||
var matches []any
|
||||
var mu sync.Mutex
|
||||
|
||||
h.MemCache.ClearMatching(
|
||||
func(k string, pm dynacache.PartitionManager) bool {
|
||||
// Avoid going through everything.
|
||||
return strings.HasPrefix(k, "/res")
|
||||
},
|
||||
func(k, v any) bool {
|
||||
if strings.Contains(k.(string), p) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
switch vv := v.(type) {
|
||||
case resource.Resources:
|
||||
// GetMatch/Match.
|
||||
for _, r := range vv {
|
||||
matches = append(matches, r)
|
||||
}
|
||||
return true
|
||||
default:
|
||||
matches = append(matches, vv)
|
||||
return true
|
||||
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
var hasID bool
|
||||
r, _ := h.ResourceSpec.ResourceCache.Get(context.Background(), dynacache.CleanKey(pathInfo.Base()))
|
||||
identity.WalkIdentitiesShallow(r, func(level int, rid identity.Identity) bool {
|
||||
hasID = true
|
||||
changes = append(changes, rid)
|
||||
return false
|
||||
})
|
||||
for _, r := range matches {
|
||||
identity.WalkIdentitiesShallow(r, func(level int, rid identity.Identity) bool {
|
||||
hasID = true
|
||||
changes = append(changes, rid)
|
||||
return false
|
||||
})
|
||||
}
|
||||
if !hasID {
|
||||
changes = append(changes, pathInfo)
|
||||
}
|
||||
|
|
|
@ -676,3 +676,37 @@ menu: main
|
|||
b.AssertFileContent("public/fr/index.html", `<a href="/fr/p1/">p1</a>`)
|
||||
b.AssertLogNotContains("WARN")
|
||||
}
|
||||
|
||||
func TestSectionPagesIssue12399(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
disableKinds = ['rss','sitemap','taxonomy','term']
|
||||
capitalizeListTitles = false
|
||||
pluralizeListTitles = false
|
||||
sectionPagesMenu = 'main'
|
||||
-- content/p1.md --
|
||||
---
|
||||
title: p1
|
||||
---
|
||||
-- content/s1/p2.md --
|
||||
---
|
||||
title: p2
|
||||
menus: main
|
||||
---
|
||||
-- content/s1/p3.md --
|
||||
---
|
||||
title: p3
|
||||
---
|
||||
-- layouts/_default/list.html --
|
||||
{{ range site.Menus.main }}<a href="{{ .URL }}">{{ .Name }}</a>{{ end }}
|
||||
-- layouts/_default/single.html --
|
||||
{{ .Title }}
|
||||
`
|
||||
|
||||
b := Test(t, files)
|
||||
|
||||
b.AssertFileExists("public/index.html", true)
|
||||
b.AssertFileContent("public/index.html", `<a href="/s1/p2/">p2</a><a href="/s1/">s1</a>`)
|
||||
}
|
||||
|
|
|
@ -659,7 +659,7 @@ func (s *Site) assembleMenus() error {
|
|||
|
||||
if sectionPagesMenu != "" {
|
||||
if err := s.pageMap.forEachPage(pagePredicates.ShouldListGlobal, func(p *pageState) (bool, error) {
|
||||
if p.IsHome() || !p.m.shouldBeCheckedForMenuDefinitions() {
|
||||
if p.Kind() != kinds.KindSection || !p.m.shouldBeCheckedForMenuDefinitions() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# Release env.
|
||||
# These will be replaced by script before release.
|
||||
HUGORELEASER_TAG=v0.125.0
|
||||
HUGORELEASER_COMMITISH=a32400b5f4e704daf7de19f44584baf77a4501ab
|
||||
HUGORELEASER_TAG=v0.125.1
|
||||
HUGORELEASER_COMMITISH=68c5ad638c2072969e47262926b912e80fd71a77
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -15,10 +15,14 @@
|
|||
package pandoc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/gohugoio/hugo/common/hexec"
|
||||
"github.com/gohugoio/hugo/htesting"
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
|
||||
"github.com/gohugoio/hugo/markup/converter"
|
||||
"github.com/gohugoio/hugo/markup/internal"
|
||||
)
|
||||
|
@ -64,6 +68,9 @@ func (c *pandocConverter) getPandocContent(src []byte, ctx converter.DocumentCon
|
|||
return src, nil
|
||||
}
|
||||
args := []string{"--mathjax"}
|
||||
if supportsCitations(c.cfg) {
|
||||
args = append(args[:], "--citeproc")
|
||||
}
|
||||
return internal.ExternallyRenderContent(c.cfg, ctx, src, binaryName, args)
|
||||
}
|
||||
|
||||
|
@ -76,6 +83,69 @@ func getPandocBinaryName() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
type pandocVersion struct {
|
||||
major, minor int64
|
||||
}
|
||||
|
||||
func (left pandocVersion) greaterThanOrEqual(right pandocVersion) bool {
|
||||
return left.major > right.major || (left.major == right.major && left.minor >= right.minor)
|
||||
}
|
||||
|
||||
var versionOnce sync.Once
|
||||
var foundPandocVersion pandocVersion
|
||||
|
||||
// getPandocVersion parses the pandoc version output
|
||||
func getPandocVersion(cfg converter.ProviderConfig) (pandocVersion, error) {
|
||||
var err error
|
||||
|
||||
versionOnce.Do(func() {
|
||||
argsv := []any{"--version"}
|
||||
|
||||
var out bytes.Buffer
|
||||
argsv = append(argsv, hexec.WithStdout(&out))
|
||||
|
||||
cmd, err := cfg.Exec.New(pandocBinary, argsv...)
|
||||
if err != nil {
|
||||
cfg.Logger.Errorf("Could not call pandoc: %v", err)
|
||||
foundPandocVersion = pandocVersion{0, 0}
|
||||
return
|
||||
}
|
||||
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
cfg.Logger.Errorf("%s --version: %v", pandocBinary, err)
|
||||
foundPandocVersion = pandocVersion{0, 0}
|
||||
return
|
||||
}
|
||||
|
||||
outbytes := bytes.Replace(out.Bytes(), []byte("\r"), []byte(""), -1)
|
||||
output := strings.Split(string(outbytes), "\n")[0]
|
||||
// Split, e.g., "pandoc 2.5" into 2 and 5 and convert them to integers
|
||||
versionStrings := strings.Split(strings.Split(output, " ")[1], ".")
|
||||
majorVersion, err := strconv.ParseInt(versionStrings[0], 10, 64)
|
||||
if err != nil {
|
||||
println(err)
|
||||
}
|
||||
minorVersion, err := strconv.ParseInt(versionStrings[1], 10, 64)
|
||||
if err != nil {
|
||||
println(err)
|
||||
}
|
||||
foundPandocVersion = pandocVersion{majorVersion, minorVersion}
|
||||
})
|
||||
|
||||
return foundPandocVersion, err
|
||||
}
|
||||
|
||||
// SupportsCitations returns true for pandoc versions >= 2.11, which include citeproc
|
||||
func supportsCitations(cfg converter.ProviderConfig) bool {
|
||||
if Supports() {
|
||||
foundPandocVersion, err := getPandocVersion(cfg)
|
||||
supportsCitations := foundPandocVersion.greaterThanOrEqual(pandocVersion{2, 11}) && err == nil
|
||||
return supportsCitations
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Supports returns whether Pandoc is installed on this computer.
|
||||
func Supports() bool {
|
||||
hasBin := getPandocBinaryName() != ""
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
qt "github.com/frankban/quicktest"
|
||||
)
|
||||
|
||||
func TestConvert(t *testing.T) {
|
||||
func setupTestConverter(t *testing.T) (*qt.C, converter.Converter, converter.ProviderConfig) {
|
||||
if !Supports() {
|
||||
t.Skip("pandoc not installed")
|
||||
}
|
||||
|
@ -38,7 +38,140 @@ func TestConvert(t *testing.T) {
|
|||
c.Assert(err, qt.IsNil)
|
||||
conv, err := p.New(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
b, err := conv.Convert(converter.RenderContext{Src: []byte("testContent")})
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(string(b.Bytes()), qt.Equals, "<p>testContent</p>\n")
|
||||
return c, conv, cfg
|
||||
}
|
||||
|
||||
func TestConvert(t *testing.T) {
|
||||
c, conv, _ := setupTestConverter(t)
|
||||
output, err := conv.Convert(converter.RenderContext{Src: []byte("testContent")})
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(string(output.Bytes()), qt.Equals, "<p>testContent</p>\n")
|
||||
}
|
||||
|
||||
func runCiteprocTest(t *testing.T, content string, expected string) {
|
||||
c, conv, cfg := setupTestConverter(t)
|
||||
if !supportsCitations(cfg) {
|
||||
t.Skip("pandoc does not support citations")
|
||||
}
|
||||
output, err := conv.Convert(converter.RenderContext{Src: []byte(content)})
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(string(output.Bytes()), qt.Equals, expected)
|
||||
}
|
||||
|
||||
func TestGetPandocVersionCallTwice(t *testing.T) {
|
||||
c, _, cfg := setupTestConverter(t)
|
||||
|
||||
version1, err1 := getPandocVersion(cfg)
|
||||
version2, err2 := getPandocVersion(cfg)
|
||||
c.Assert(version1, qt.Equals, version2)
|
||||
c.Assert(err1, qt.IsNil)
|
||||
c.Assert(err2, qt.IsNil)
|
||||
}
|
||||
|
||||
func TestPandocVersionEquality(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
v1 := pandocVersion{1, 0}
|
||||
v2 := pandocVersion{2, 0}
|
||||
v3 := pandocVersion{2, 2}
|
||||
v4 := pandocVersion{1, 2}
|
||||
v5 := pandocVersion{2, 11}
|
||||
|
||||
// 1 >= 1 -> true
|
||||
c.Assert(v1.greaterThanOrEqual(v1), qt.IsTrue)
|
||||
|
||||
// 1 >= 2 -> false, 2 >= 1 -> tru
|
||||
c.Assert(v1.greaterThanOrEqual(v2), qt.IsFalse)
|
||||
c.Assert(v2.greaterThanOrEqual(v1), qt.IsTrue)
|
||||
|
||||
// 2.0 >= 2.2 -> false, 2.2 >= 2.0 -> true
|
||||
c.Assert(v2.greaterThanOrEqual(v3), qt.IsFalse)
|
||||
c.Assert(v3.greaterThanOrEqual(v2), qt.IsTrue)
|
||||
|
||||
// 2.2 >= 1.2 -> true, 1.2 >= 2.2 -> false
|
||||
c.Assert(v3.greaterThanOrEqual(v4), qt.IsTrue)
|
||||
c.Assert(v4.greaterThanOrEqual(v3), qt.IsFalse)
|
||||
|
||||
// 2.11 >= 2.2 -> true, 2.2 >= 2.11 -> false
|
||||
c.Assert(v5.greaterThanOrEqual(v3), qt.IsTrue)
|
||||
c.Assert(v3.greaterThanOrEqual(v5), qt.IsFalse)
|
||||
}
|
||||
|
||||
func TestCiteprocWithHugoMeta(t *testing.T) {
|
||||
content := `
|
||||
---
|
||||
title: Test
|
||||
published: 2022-05-30
|
||||
---
|
||||
testContent
|
||||
`
|
||||
expected := "<p>testContent</p>\n"
|
||||
runCiteprocTest(t, content, expected)
|
||||
}
|
||||
|
||||
func TestCiteprocWithPandocMeta(t *testing.T) {
|
||||
content := `
|
||||
---
|
||||
---
|
||||
---
|
||||
...
|
||||
testContent
|
||||
`
|
||||
expected := "<p>testContent</p>\n"
|
||||
runCiteprocTest(t, content, expected)
|
||||
}
|
||||
|
||||
func TestCiteprocWithBibliography(t *testing.T) {
|
||||
content := `
|
||||
---
|
||||
---
|
||||
---
|
||||
bibliography: testdata/bibliography.bib
|
||||
...
|
||||
testContent
|
||||
`
|
||||
expected := "<p>testContent</p>\n"
|
||||
runCiteprocTest(t, content, expected)
|
||||
}
|
||||
|
||||
func TestCiteprocWithExplicitCitation(t *testing.T) {
|
||||
content := `
|
||||
---
|
||||
---
|
||||
---
|
||||
bibliography: testdata/bibliography.bib
|
||||
...
|
||||
@Doe2022
|
||||
`
|
||||
expected := `<p><span class="citation" data-cites="Doe2022">Doe and Mustermann
|
||||
(2022)</span></p>
|
||||
<div id="refs" class="references csl-bib-body hanging-indent"
|
||||
role="doc-bibliography">
|
||||
<div id="ref-Doe2022" class="csl-entry" role="doc-biblioentry">
|
||||
Doe, Jane, and Max Mustermann. 2022. <span>“A Treatise on Hugo
|
||||
Tests.”</span> <em>Hugo Websites</em>.
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
runCiteprocTest(t, content, expected)
|
||||
}
|
||||
|
||||
func TestCiteprocWithNocite(t *testing.T) {
|
||||
content := `
|
||||
---
|
||||
---
|
||||
---
|
||||
bibliography: testdata/bibliography.bib
|
||||
nocite: |
|
||||
@*
|
||||
...
|
||||
`
|
||||
expected := `<div id="refs" class="references csl-bib-body hanging-indent"
|
||||
role="doc-bibliography">
|
||||
<div id="ref-Doe2022" class="csl-entry" role="doc-biblioentry">
|
||||
Doe, Jane, and Max Mustermann. 2022. <span>“A Treatise on Hugo
|
||||
Tests.”</span> <em>Hugo Websites</em>.
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
runCiteprocTest(t, content, expected)
|
||||
}
|
||||
|
|
6
markup/pandoc/testdata/bibliography.bib
vendored
Normal file
6
markup/pandoc/testdata/bibliography.bib
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
@article{Doe2022,
|
||||
author = "Jane Doe and Max Mustermann",
|
||||
title = "A Treatise on Hugo Tests",
|
||||
journal = "Hugo Websites",
|
||||
year = "2022",
|
||||
}
|
|
@ -18,6 +18,7 @@ import (
|
|||
"testing"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"github.com/gohugoio/hugo/htesting/hqt"
|
||||
)
|
||||
|
||||
func TestHexStringToColor(t *testing.T) {
|
||||
|
@ -119,8 +120,8 @@ func TestReplaceColorInPalette(t *testing.T) {
|
|||
|
||||
func TestColorLuminance(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
c.Assert(hexStringToColor("#000000").Luminance(), qt.Equals, 0.0)
|
||||
c.Assert(hexStringToColor("#768a9a").Luminance(), qt.Equals, 0.24361603589088263)
|
||||
c.Assert(hexStringToColor("#d5bc9f").Luminance(), qt.Equals, 0.5261577672685374)
|
||||
c.Assert(hexStringToColor("#ffffff").Luminance(), qt.Equals, 1.0)
|
||||
c.Assert(hexStringToColor("#000000").Luminance(), hqt.IsSameFloat64, 0.0)
|
||||
c.Assert(hexStringToColor("#768a9a").Luminance(), hqt.IsSameFloat64, 0.24361603589088263)
|
||||
c.Assert(hexStringToColor("#d5bc9f").Luminance(), hqt.IsSameFloat64, 0.5261577672685374)
|
||||
c.Assert(hexStringToColor("#ffffff").Luminance(), hqt.IsSameFloat64, 1.0)
|
||||
}
|
||||
|
|
|
@ -327,3 +327,34 @@ Styles: {{ $r.RelPermalink }}
|
|||
|
||||
b.AssertFileContent("public/index.html", "Styles: /scss/main.css")
|
||||
}
|
||||
|
||||
func TestRebuildAssetGetMatch(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !scss.Supports() {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
files := `
|
||||
-- assets/scss/main.scss --
|
||||
b {
|
||||
color: red;
|
||||
}
|
||||
-- layouts/index.html --
|
||||
{{ $r := resources.GetMatch "scss/main.scss" | toCSS }}
|
||||
T1: {{ $r.Content }}
|
||||
`
|
||||
|
||||
b := hugolib.NewIntegrationTestBuilder(
|
||||
hugolib.IntegrationTestConfig{
|
||||
T: t,
|
||||
TxtarString: files,
|
||||
NeedsOsFS: true,
|
||||
Running: true,
|
||||
}).Build()
|
||||
|
||||
b.AssertFileContent("public/index.html", `color: red`)
|
||||
|
||||
b.EditFiles("assets/scss/main.scss", `b { color: blue; }`).Build()
|
||||
|
||||
b.AssertFileContent("public/index.html", `color: blue`)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ Renders an embedded YouTube video.
|
|||
*/}}
|
||||
|
||||
{{- $pc := .Page.Site.Config.Privacy.YouTube }}
|
||||
{{- $remoteErrID := "err-youtube-remote" }}
|
||||
{{- if not $pc.Disable }}
|
||||
{{- with $id := or (.Get "id") (.Get 0) }}
|
||||
|
||||
|
@ -31,12 +32,12 @@ Renders an embedded YouTube video.
|
|||
{{- $data := dict }}
|
||||
{{- with resources.GetRemote $url }}
|
||||
{{- with .Err }}
|
||||
{{- errorf "The %q shortcode was unable to get remote resource %q. %s. See %s" $.Name $url . $.Position }}
|
||||
{{- erroridf $remoteErrID "The %q shortcode was unable to get remote resource %q. %s. See %s" $.Name $url . $.Position }}
|
||||
{{- else }}
|
||||
{{- $data = .Content | transform.Unmarshal }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- errorf "The %q shortcode was unable to get remote resource %q. See %s" $.Name $url $.Position }}
|
||||
{{- erroridf $remoteErrID "The %q shortcode was unable to get remote resource %q. See %s" $.Name $url $.Position }}
|
||||
{{- end }}
|
||||
|
||||
{{/* Set defaults. */}}
|
||||
|
|
Loading…
Reference in a new issue