hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 6f7bf3f2d7eda178d0dba4a6bf3dfa50229df7ae
parent 9e904d756be02ca30e4cd9abb1eae8ba01f9c8af
Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date:   Mon, 30 May 2022 20:42:46 +0200

Fix indentation in highlight shortcode

This commit adds a new `.InnerDeindent` method to the shortcode context, which is `.Inner` with any
indendation removed. This is then used in the built-in `highlight` shortcode to prevent the extra
whitespace getting hightlighted.

Fixes #4717

Diffstat:
Mdocs/content/en/variables/shortcodes.md | 4++++
Mhugolib/shortcode.go | 29++++++++++++++++++++++++++++-
Mhugolib/shortcode_test.go | 44++++++++++++++++++++++++++++++++++++++++++++
Mtpl/tplimpl/embedded/templates/shortcodes/highlight.html | 4++--
Mtpl/tplimpl/template_ast_transformers.go | 2+-
5 files changed, 79 insertions(+), 4 deletions(-)
diff --git a/docs/content/en/variables/shortcodes.md b/docs/content/en/variables/shortcodes.md
@@ -45,4 +45,8 @@ toc: false
 [markdownshortcode]: /content-management/shortcodes/#shortcodes-with-markdown
 [shortcodes]: /templates/shortcode-templates/
 
+.InnerDeindent {{< new-in "0.100.0" >}}
+: Gets the `.Inner` with any indentation removed. This is what's used in the built-in `{{</* highlight */>}}` shortcode.
+
+
 
diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go
@@ -62,6 +62,12 @@ type ShortcodeWithPage struct {
 	// this ordinal will represent the position of this shortcode in the page content.
 	Ordinal int
 
+	// Indentation before the opening shortcode in the source.
+	indentation string
+
+	innerDeindentInit sync.Once
+	innerDeindent     template.HTML
+
 	// pos is the position in bytes in the source file. Used for error logging.
 	posInit   sync.Once
 	posOffset int
@@ -70,6 +76,27 @@ type ShortcodeWithPage struct {
 	scratch *maps.Scratch
 }
 
+// InnerDeindent returns the (potentially de-indented) inner content of the shortcode.
+func (scp *ShortcodeWithPage) InnerDeindent() template.HTML {
+	if scp.indentation == "" {
+		return scp.Inner
+	}
+	scp.innerDeindentInit.Do(func() {
+		b := bp.GetBuffer()
+		text.VisitLinesAfter(string(scp.Inner), func(s string) {
+			if strings.HasPrefix(s, scp.indentation) {
+				b.WriteString(strings.TrimPrefix(s, scp.indentation))
+			} else {
+				b.WriteString(s)
+			}
+		})
+		scp.innerDeindent = template.HTML(b.String())
+		bp.PutBuffer(b)
+	})
+
+	return scp.innerDeindent
+}
+
 // Position returns this shortcode's detailed position. Note that this information
 // may be expensive to calculate, so only use this in error situations.
 func (scp *ShortcodeWithPage) Position() text.Position {
@@ -326,7 +353,7 @@ func renderShortcode(
 		hasVariants = hasVariants || more
 	}
 
-	data := &ShortcodeWithPage{Ordinal: sc.ordinal, posOffset: sc.pos, Params: sc.params, Page: newPageForShortcode(p), Parent: parent, Name: sc.name}
+	data := &ShortcodeWithPage{Ordinal: sc.ordinal, posOffset: sc.pos, indentation: sc.indentation, Params: sc.params, Page: newPageForShortcode(p), Parent: parent, Name: sc.name}
 	if sc.params != nil {
 		data.IsNamedParams = reflect.TypeOf(sc.params).Kind() == reflect.Map
 	}
diff --git a/hugolib/shortcode_test.go b/hugolib/shortcode_test.go
@@ -1009,3 +1009,47 @@ echo "foo";
 	b.AssertFileContent("public/p1/index.html", "<pre><code>echo &quot;foo&quot;;\n</code></pre>")
 
 }
+
+func TestShortcodeHighlightDeindent(t *testing.T) {
+	t.Parallel()
+
+	files := `
+-- config.toml --
+[markup]
+[markup.highlight]
+codeFences = true
+noClasses = false
+-- content/p1.md --
+---
+title: "p1"
+---
+
+## Indent 5 Spaces
+
+     {{< highlight bash >}}
+     line 1;
+     line 2;
+     line 3;
+     {{< /highlight >}}
+
+-- layouts/_default/single.html --
+{{ .Content }}
+`
+
+	b := NewIntegrationTestBuilder(
+		IntegrationTestConfig{
+			T:           t,
+			TxtarString: files,
+			Running:     true,
+		},
+	).Build()
+
+	b.AssertFileContent("public/p1/index.html", `
+<pre><code> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">line 1<span class="p">;</span>
+</span></span><span class="line"><span class="cl">line 2<span class="p">;</span>
+</span></span><span class="line"><span class="cl">line 3<span class="p">;</span></span></span></code></pre></div>
+</code></pre>
+
+	`)
+
+}
diff --git a/tpl/tplimpl/embedded/templates/shortcodes/highlight.html b/tpl/tplimpl/embedded/templates/shortcodes/highlight.html
@@ -1 +1 @@
-{{ if len .Params | eq 2 }}{{ highlight (trim .Inner "\n\r") (.Get 0) (.Get 1) }}{{ else }}{{ highlight (trim .Inner "\n\r") (.Get 0) "" }}{{ end }}-
\ No newline at end of file
+{{ if len .Params | eq 2 }}{{ highlight (trim .InnerDeindent "\n\r") (.Get 0) (.Get 1) }}{{ else }}{{ highlight (trim .InnerDeindent "\n\r") (.Get 0) "" }}{{ end }}+
\ No newline at end of file
diff --git a/tpl/tplimpl/template_ast_transformers.go b/tpl/tplimpl/template_ast_transformers.go
@@ -272,7 +272,7 @@ func (c *templateContext) collectInner(n *parse.CommandNode) {
 			idents = nt.Ident
 		}
 
-		if c.hasIdent(idents, "Inner") {
+		if c.hasIdent(idents, "Inner") || c.hasIdent(idents, "InnerDeindent") {
 			c.t.parseInfo.IsInner = true
 			break
 		}