shithub: hugo

Download patch

ref: c52045bbb38cbf64b9cb39352230060aa122cc9f
parent: 8ed2a1caa9e0892d5bf97ed1b7279befa159f764
author: Bjørn Erik Pedersen <[email protected]>
date: Thu Jan 31 06:53:21 EST 2019

Fix some inline shortcode issues

Fixes #5645
Fixes #5653

--- a/hugolib/shortcode.go
+++ b/hugolib/shortcode.go
@@ -338,14 +338,9 @@
 
 	if sc.isInline {
 		key := newScKeyFromLangAndOutputFormat(lang, p.outputFormats[0], placeholder)
-		if !s.enableInlineShortcodes {
-			m[key] = func() (string, error) {
-				return "", nil
-			}
-		} else {
-			m[key] = func() (string, error) {
-				return renderShortcode(key, sc, nil, p)
-			}
+		m[key] = func() (string, error) {
+			return renderShortcode(key, sc, nil, p)
+
 		}
 
 		return m
@@ -372,6 +367,9 @@
 	var tmpl tpl.Template
 
 	if sc.isInline {
+		if !p.s.enableInlineShortcodes {
+			return "", nil
+		}
 		templName := path.Join("_inline_shortcode", p.Path(), sc.name)
 		if sc.isClosing {
 			templStr := sc.innerString()
@@ -542,6 +540,10 @@
 		if !found && key.Suffix != "html" {
 			key.Suffix = "html"
 			renderFn, found = s.contentShortcodes.Get(key)
+			if !found {
+				key.OutputFormat = "HTML"
+				renderFn, found = s.contentShortcodes.Get(key)
+			}
 		}
 
 		if !found {
--- a/hugolib/shortcode_test.go
+++ b/hugolib/shortcode_test.go
@@ -1076,11 +1076,8 @@
 
 				b := newTestSitesBuilder(t)
 				b.WithConfigFile("toml", conf)
-				b.WithContent("page-md-shortcode.md", `---
-title: "Hugo"
----
 
-FIRST:{{< myshort.inline "first" >}}
+				shortcodeContent := `FIRST:{{< myshort.inline "first" >}}
 Page: {{ .Page.Title }}
 Seq: {{ seq 3 }}
 Param: {{ .Get 0 }}
@@ -1087,29 +1084,59 @@
 {{< /myshort.inline >}}:END:
 
 SECOND:{{< myshort.inline "second" />}}:END
+NEW INLINE:  {{< n1.inline "5" >}}W1: {{ seq (.Get 0) }}{{< /n1.inline >}}:END:
+INLINE IN INNER: {{< outer >}}{{< n2.inline >}}W2: {{ seq 4 }}{{< /n2.inline >}}{{< /outer >}}:END:
+REUSED INLINE IN INNER: {{< outer >}}{{< n1.inline "3" />}}{{< /outer >}}:END:
+`
 
-`)
+				b.WithContent("page-md-shortcode.md", `---
+title: "Hugo"
+---
+`+shortcodeContent)
 
+				b.WithContent("_index.md", `---
+title: "Hugo Home"
+---
+
+`+shortcodeContent)
+
 				b.WithTemplatesAdded("layouts/_default/single.html", `
 CONTENT:{{ .Content }}
 `)
 
+				b.WithTemplatesAdded("layouts/index.html", `
+CONTENT:{{ .Content }}
+`)
+
+				b.WithTemplatesAdded("layouts/shortcodes/outer.html", `Inner: {{ .Inner }}`)
+
 				b.CreateSites().Build(BuildCfg{})
 
+				shouldContain := []string{
+					"Seq: [1 2 3]",
+					"Param: first",
+					"Param: second",
+					"NEW INLINE:  W1: [1 2 3 4 5]",
+					"INLINE IN INNER: Inner: W2: [1 2 3 4]",
+					"REUSED INLINE IN INNER: Inner: W1: [1 2 3]",
+				}
+
 				if enableInlineShortcodes {
 					b.AssertFileContent("public/page-md-shortcode/index.html",
-						"Page: Hugo",
-						"Seq: [1 2 3]",
-						"Param: first",
-						"Param: second",
+						shouldContain...,
 					)
+					b.AssertFileContent("public/index.html",
+						shouldContain...,
+					)
 				} else {
 					b.AssertFileContent("public/page-md-shortcode/index.html",
 						"FIRST::END",
 						"SECOND::END",
+						"NEW INLINE:  :END",
+						"INLINE IN INNER: Inner: :END:",
+						"REUSED INLINE IN INNER: Inner: :END:",
 					)
 				}
-
 			})
 
 	}
--- a/parser/pageparser/pagelexer_shortcode.go
+++ b/parser/pageparser/pagelexer_shortcode.go
@@ -280,6 +280,7 @@
 			return l.errorf("got closing shortcode, but none is open")
 		}
 		l.closingState++
+		l.isInline = false
 		l.emit(tScClose)
 	case r == '\\':
 		l.ignore()
--- a/parser/pageparser/pageparser_shortcode_test.go
+++ b/parser/pageparser/pageparser_shortcode_test.go
@@ -24,6 +24,7 @@
 	tstSCClose   = nti(tScClose, "/")
 	tstSC1       = nti(tScName, "sc1")
 	tstSC1Inline = nti(tScNameInline, "sc1.inline")
+	tstSC2Inline = nti(tScNameInline, "sc2.inline")
 	tstSC2       = nti(tScName, "sc2")
 	tstSC3       = nti(tScName, "sc3")
 	tstSCSlash   = nti(tScName, "sc/sub")
@@ -152,6 +153,9 @@
 	{"basic inline", `{{< sc1.inline >}}Hello World{{< /sc1.inline >}}`, []Item{tstLeftNoMD, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSCClose, tstSC1Inline, tstRightNoMD, tstEOF}},
 	{"basic inline with space", `{{< sc1.inline >}}Hello World{{< / sc1.inline >}}`, []Item{tstLeftNoMD, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSCClose, tstSC1Inline, tstRightNoMD, tstEOF}},
 	{"inline self closing", `{{< sc1.inline >}}Hello World{{< /sc1.inline >}}Hello World{{< sc1.inline />}}`, []Item{tstLeftNoMD, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSCClose, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSC1Inline, tstSCClose, tstRightNoMD, tstEOF}},
+	{"inline self closing, then a new inline", `{{< sc1.inline >}}Hello World{{< /sc1.inline >}}Hello World{{< sc1.inline />}}{{< sc2.inline >}}Hello World{{< /sc2.inline >}}`, []Item{
+		tstLeftNoMD, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSCClose, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSC1Inline, tstSCClose, tstRightNoMD,
+		tstLeftNoMD, tstSC2Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSCClose, tstSC2Inline, tstRightNoMD, tstEOF}},
 	{"inline with template syntax", `{{< sc1.inline >}}{{ .Get 0 }}{{ .Get 1 }}{{< /sc1.inline >}}`, []Item{tstLeftNoMD, tstSC1Inline, tstRightNoMD, nti(tText, "{{ .Get 0 }}"), nti(tText, "{{ .Get 1 }}"), tstLeftNoMD, tstSCClose, tstSC1Inline, tstRightNoMD, tstEOF}},
 	{"inline with nested shortcode (not supported)", `{{< sc1.inline >}}Hello World{{< sc1 >}}{{< /sc1.inline >}}`, []Item{tstLeftNoMD, tstSC1Inline, tstRightNoMD, tstText, nti(tError, "inline shortcodes do not support nesting")}},
 	{"inline case mismatch", `{{< sc1.Inline >}}Hello World{{< /sc1.Inline >}}`, []Item{tstLeftNoMD, nti(tError, "period in shortcode name only allowed for inline identifiers")}},
@@ -160,10 +164,12 @@
 func TestShortcodeLexer(t *testing.T) {
 	t.Parallel()
 	for i, test := range shortCodeLexerTests {
-		items := collect([]byte(test.input), true, lexMainSection)
-		if !equal(items, test.items) {
-			t.Errorf("[%d] %s: got\n\t%v\nexpected\n\t%v", i, test.name, items, test.items)
-		}
+		t.Run(test.name, func(t *testing.T) {
+			items := collect([]byte(test.input), true, lexMainSection)
+			if !equal(items, test.items) {
+				t.Errorf("[%d] %s: got\n\t%v\nexpected\n\t%v", i, test.name, items, test.items)
+			}
+		})
 	}
 }
 
--- a/tpl/tplimpl/template.go
+++ b/tpl/tplimpl/template.go
@@ -366,7 +366,8 @@
 }
 
 type textTemplate struct {
-	t *texttemplate.Template
+	mu sync.RWMutex
+	t  *texttemplate.Template
 }
 
 func (t *textTemplate) Parse(name, tpl string) (tpl.Template, error) {
@@ -374,11 +375,17 @@
 }
 
 func (t *textTemplate) Lookup(name string) (tpl.Template, bool) {
+	t.mu.RLock()
+	defer t.mu.RUnlock()
+
 	tpl := t.t.Lookup(name)
 	return tpl, tpl != nil
 }
 
 func (t *textTemplate) parSeIn(tt *texttemplate.Template, name, tpl string) (*texttemplate.Template, error) {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+
 	templ, err := tt.New(name).Parse(tpl)
 	if err != nil {
 		return nil, err