markup/highlight: Allow lineNos to be true, false, "inline", or "table"

Closes #13481
This commit is contained in:
Joe Mooring
2025-04-22 19:42:04 -07:00
committed by Bjørn Erik Pedersen
parent af5051e759
commit 3158a51283
3 changed files with 112 additions and 7 deletions
+34 -6
View File
@@ -60,7 +60,7 @@ type Config struct {
NoClasses bool
// When set, line numbers will be printed.
LineNos bool
LineNos any
LineNumbersInTable bool
// When set, add links to line numbers
@@ -85,16 +85,44 @@ type Config struct {
GuessSyntax bool
}
func (cfg Config) toHTMLOptions() []html.Option {
var lineAnchors string
const errLineNosMsg = `lineNos must be one of true, false, "inline", or "table"; got %[1]v (%[1]T)`
func (cfg Config) toHTMLOptions() ([]html.Option, error) {
var (
lineAnchors string
lineNos bool
inTable = cfg.LineNumbersInTable
)
if cfg.LineAnchors != "" {
lineAnchors = cfg.LineAnchors + "-"
}
switch v := cfg.LineNos.(type) {
case string:
switch v {
case "inline":
lineNos = true
inTable = false
case "table":
lineNos = true
inTable = true
default:
return nil, fmt.Errorf(errLineNosMsg, v)
}
case bool:
lineNos = v
case nil:
lineNos = false
default:
return nil, fmt.Errorf(errLineNosMsg, v)
}
options := []html.Option{
html.TabWidth(cfg.TabWidth),
html.WithLineNumbers(cfg.LineNos),
html.WithLineNumbers(lineNos),
html.BaseLineNumber(cfg.LineNoStart),
html.LineNumbersInTable(cfg.LineNumbersInTable),
html.LineNumbersInTable(inTable),
html.WithClasses(!cfg.NoClasses),
html.WithLinkableLineNumbers(cfg.AnchorLineNos, lineAnchors),
html.InlineCode(cfg.Hl_inline),
@@ -117,7 +145,7 @@ func (cfg Config) toHTMLOptions() []html.Option {
}
}
return options
return options, nil
}
func applyOptions(opts any, cfg *Config) error {
+5 -1
View File
@@ -205,7 +205,11 @@ func highlight(fw hugio.FlexiWriter, code, lang string, attributes []attributes.
writeDivStart(w, attributes, cfg.WrapperClass)
}
options := cfg.toHTMLOptions()
options, err := cfg.toHTMLOptions()
if err != nil {
return 0, 0, err
}
var wrapper html.PreWrapper
if cfg.Hl_inline {
@@ -14,8 +14,10 @@
package highlight_test
import (
"strings"
"testing"
qt "github.com/frankban/quicktest"
"github.com/gohugoio/hugo/hugolib"
)
@@ -129,3 +131,74 @@ xəx := 0
<div class="highlight no-prose"><pre
`)
}
func TestHighlightLineNos(t *testing.T) {
t.Parallel()
files := `
-- config.toml --
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
[markup.highlight]
noClasses = false
lineNoStart = 42
#LINENOS
-- content/_index.md --
---
title: home
---
§§§go
aaa
§§§
-- layouts/index.html --
{{ .Content }}
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/index.html",
`<span class="nx">aaa</span>`,
`! <table class="lntable">`,
`! 42`,
)
f := strings.ReplaceAll(files, "#LINENOS", `linenos = false`)
b = hugolib.Test(t, f)
b.AssertFileContent("public/index.html",
`<span class="nx">aaa</span>`,
`! <table class="lntable">`,
`! 42`,
)
f = strings.ReplaceAll(files, "#LINENOS", `linenos = true`)
b = hugolib.Test(t, f)
b.AssertFileContent("public/index.html",
`<span class="nx">aaa</span>`,
`<table class="lntable">`,
`42`,
)
f = strings.ReplaceAll(files, "#LINENOS", `linenos = "table"`)
b = hugolib.Test(t, f)
b.AssertFileContent("public/index.html",
`<span class="nx">aaa</span>`,
`<table class="lntable">`,
`42`,
)
f = strings.ReplaceAll(files, "#LINENOS", `linenos = "inline"`)
b = hugolib.Test(t, f)
b.AssertFileContent("public/index.html",
`<span class="nx">aaa</span>`,
`! <table class="lntable">`,
`42`,
)
want := `.* lineNos must be one of .*`
f = strings.ReplaceAll(files, "#LINENOS", `linenos = "foo"`)
b, err := hugolib.TestE(t, f)
b.Assert(err, qt.ErrorMatches, want)
f = strings.ReplaceAll(files, "#LINENOS", `linenos = 123`)
b, err = hugolib.TestE(t, f)
b.Assert(err, qt.ErrorMatches, want)
}