From d863dde6c653700fb540d7e4dd6605c7186f59da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Wed, 15 Jun 2022 13:51:29 +0200 Subject: [PATCH] markup/highlight: Add hl_inline option Closes #9442 Closes #9635 Closes #9638 --- markup/highlight/config.go | 4 ++ markup/highlight/highlight.go | 87 ++++++++++++++++++++---- markup/highlight/integration_test.go | 85 +++++++++++++++++++++++ markup/internal/attributes/attributes.go | 1 + 4 files changed, 163 insertions(+), 14 deletions(-) create mode 100644 markup/highlight/integration_test.go diff --git a/markup/highlight/config.go b/markup/highlight/config.go index 80991f21b..d55958d35 100644 --- a/markup/highlight/config.go +++ b/markup/highlight/config.go @@ -72,6 +72,9 @@ type Config struct { // A space separated list of line numbers, e.g. “3-8 10-20”. Hl_Lines string + // If set, the markup will not be wrapped in any container. + Hl_inline bool + // A parsed and ready to use list of line ranges. HL_lines_parsed [][2]int `json:"-"` @@ -93,6 +96,7 @@ func (cfg Config) ToHTMLOptions() []html.Option { html.LineNumbersInTable(cfg.LineNumbersInTable), html.WithClasses(!cfg.NoClasses), html.LinkableLineNumbers(cfg.AnchorLineNos, lineAnchors), + html.InlineCode(cfg.Hl_inline), } if cfg.Hl_Lines != "" || cfg.HL_lines_parsed != nil { diff --git a/markup/highlight/highlight.go b/markup/highlight/highlight.go index 7e5704132..5b19d6e8e 100644 --- a/markup/highlight/highlight.go +++ b/markup/highlight/highlight.go @@ -88,6 +88,7 @@ func (h chromaHighlighter) HighlightCodeBlock(ctx hooks.CodeblockContext, opts a var b strings.Builder attributes := ctx.(hooks.AttributesOptionsSliceProvider).AttributesSlice() + options := ctx.Options() if err := applyOptionsFromMap(options, &cfg); err != nil { @@ -108,8 +109,13 @@ func (h chromaHighlighter) HighlightCodeBlock(ctx hooks.CodeblockContext, opts a return HightlightResult{}, err } + highlighted := b.String() + if high == 0 { + high = len(highlighted) + } + return HightlightResult{ - highlighted: template.HTML(b.String()), + highlighted: template.HTML(highlighted), innerLow: low, innerHigh: high, }, nil @@ -117,6 +123,7 @@ func (h chromaHighlighter) HighlightCodeBlock(ctx hooks.CodeblockContext, opts a func (h chromaHighlighter) RenderCodeblock(w hugio.FlexiWriter, ctx hooks.CodeblockContext) error { cfg := h.cfg + attributes := ctx.(hooks.AttributesOptionsSliceProvider).AttributesSlice() if err := applyOptionsFromMap(ctx.Options(), &cfg); err != nil { @@ -158,8 +165,6 @@ func (h HightlightResult) Inner() template.HTML { } func highlight(fw hugio.FlexiWriter, code, lang string, attributes []attributes.Attribute, cfg Config) (int, int, error) { - var low, high int - var lexer chroma.Lexer if lang != "" { lexer = lexers.Get(lang) @@ -176,11 +181,15 @@ func highlight(fw hugio.FlexiWriter, code, lang string, attributes []attributes. w := &byteCountFlexiWriter{delegate: fw} if lexer == nil { - wrapper := getPreWrapper(lang, w) - fmt.Fprint(w, wrapper.Start(true, "")) - fmt.Fprint(w, gohtml.EscapeString(code)) - fmt.Fprint(w, wrapper.End(true)) - return low, high, nil + if cfg.Hl_inline { + fmt.Fprint(w, fmt.Sprintf("%s", inlineCodeAttrs(lang), gohtml.EscapeString(code))) + } else { + preWrapper := getPreWrapper(lang, w) + fmt.Fprint(w, preWrapper.Start(true, "")) + fmt.Fprint(w, gohtml.EscapeString(code)) + fmt.Fprint(w, preWrapper.End(true)) + } + return 0, 0, nil } style := styles.Get(cfg.Style) @@ -194,20 +203,51 @@ func highlight(fw hugio.FlexiWriter, code, lang string, attributes []attributes. return 0, 0, err } + if !cfg.Hl_inline { + writeDivStart(w, attributes) + } + options := cfg.ToHTMLOptions() - preWrapper := getPreWrapper(lang, w) - options = append(options, html.WithPreWrapper(preWrapper)) + var wrapper html.PreWrapper + + if cfg.Hl_inline { + wrapper = startEnd{ + start: func(code bool, styleAttr string) string { + if code { + return fmt.Sprintf(``, inlineCodeAttrs(lang)) + } + return `` + }, + end: func(code bool) string { + if code { + return `` + } + + return `` + }, + } + + } else { + wrapper = getPreWrapper(lang, w) + } + + options = append(options, html.WithPreWrapper(wrapper)) formatter := html.New(options...) - writeDivStart(w, attributes) - if err := formatter.Format(w, style, iterator); err != nil { return 0, 0, err } - writeDivEnd(w) - return preWrapper.low, preWrapper.high, nil + if !cfg.Hl_inline { + writeDivEnd(w) + } + + if p, ok := wrapper.(*preWrapper); ok { + return p.low, p.high, nil + } + + return 0, 0, nil } func getPreWrapper(language string, writeCounter *byteCountFlexiWriter) *preWrapper { @@ -232,6 +272,12 @@ func (p *preWrapper) Start(code bool, styleAttr string) string { return w.String() } +func inlineCodeAttrs(lang string) string { + if lang == "" { + } + return fmt.Sprintf(` class="code-inline language-%s"`, lang) +} + func WritePreStart(w io.Writer, language, styleAttr string) { fmt.Fprintf(w, `
`, styleAttr)
 	fmt.Fprint(w, "}}(message "this highlight shortcode"){{< /highlight >}}:End.
+Inline Unknown:{{< highlight foo "hl_inline=true" >}}(message "this highlight shortcode"){{< /highlight >}}:End.
+
+## Inline in code block
+
+Not sure if this makes sense, but add a test for it:
+
+§§§bash {hl_inline=true}
+(message "highlight me")
+§§§
+
+## HighlightCodeBlock in hook
+
+§§§html
+(message "highlight me 2")
+§§§
+
+## Unknown lexer
+
+§§§foo {hl_inline=true}
+(message "highlight me 3")
+§§§
+
+
+-- layouts/_default/_markup/render-codeblock-html.html --
+{{ $opts := dict "hl_inline" true }}
+{{ $result := transform.HighlightCodeBlock . $opts }}
+HighlightCodeBlock: Wrapped:{{ $result.Wrapped  }}|Inner:{{ $result.Inner }}
+-- layouts/_default/single.html --
+{{ .Content }}
+`
+
+	b := hugolib.NewIntegrationTestBuilder(
+		hugolib.IntegrationTestConfig{
+			T:           t,
+			TxtarString: files,
+			NeedsOsFS:   false,
+		},
+	).Build()
+
+	b.AssertFileContent("public/p1/index.html",
+		"Inline:(message "this highlight shortcode"):End.",
+		"Inline Unknown:(message "this highlight shortcode"):End.",
+		"Not sure if this makes sense, but add a test for it:

\n(message "highlight me")\n", + "HighlightCodeBlock: Wrapped:(message "highlight me 2")|Inner:(message "highlight me 2")", + "(message "highlight me 3")\n", + ) +} diff --git a/markup/internal/attributes/attributes.go b/markup/internal/attributes/attributes.go index edf857822..688740983 100644 --- a/markup/internal/attributes/attributes.go +++ b/markup/internal/attributes/attributes.go @@ -30,6 +30,7 @@ var chromaHightlightProcessingAttributes = map[string]bool{ "anchorLineNos": true, "guessSyntax": true, "hl_Lines": true, + "hl_inline": true, "lineAnchors": true, "lineNos": true, "lineNoStart": true,