mirror of
				https://github.com/gohugoio/hugo.git
				synced 2024-05-11 05:54:58 +00:00 
			
		
		
		
	@@ -22,6 +22,7 @@ import (
 | 
			
		||||
	"runtime/debug"
 | 
			
		||||
 | 
			
		||||
	"github.com/gohugoio/hugo/markup/goldmark/internal/extensions/attributes"
 | 
			
		||||
	"github.com/yuin/goldmark/ast"
 | 
			
		||||
 | 
			
		||||
	"github.com/gohugoio/hugo/identity"
 | 
			
		||||
 | 
			
		||||
@@ -321,7 +322,28 @@ func newHighlighting(cfg highlight.Config) goldmark.Extender {
 | 
			
		||||
					highlight.WriteCodeTag(w, language)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				w.WriteString(`<div class="highlight">`)
 | 
			
		||||
 | 
			
		||||
				w.WriteString(`<div class="highlight`)
 | 
			
		||||
 | 
			
		||||
				var attributes []ast.Attribute
 | 
			
		||||
				if ctx.Attributes() != nil {
 | 
			
		||||
					attributes = ctx.Attributes().All()
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if attributes != nil {
 | 
			
		||||
					class, found := ctx.Attributes().GetString("class")
 | 
			
		||||
					if found {
 | 
			
		||||
						w.WriteString(" ")
 | 
			
		||||
						w.Write(util.EscapeHTML(class.([]byte)))
 | 
			
		||||
 | 
			
		||||
					}
 | 
			
		||||
					_, _ = w.WriteString("\"")
 | 
			
		||||
					renderAttributes(w, true, attributes...)
 | 
			
		||||
				} else {
 | 
			
		||||
					_, _ = w.WriteString("\"")
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				w.WriteString(">")
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -226,6 +226,25 @@ func TestConvertAttributes(t *testing.T) {
 | 
			
		||||
			"> foo\n> bar\n{#id .className attrName=attrValue class=\"class1 class2\"}\n",
 | 
			
		||||
			"<blockquote id=\"id\" class=\"className class1 class2\"><p>foo\nbar</p>\n</blockquote>\n",
 | 
			
		||||
		},
 | 
			
		||||
		/*{
 | 
			
		||||
			// TODO(bep) this needs an upstream fix, see https://github.com/yuin/goldmark/issues/195
 | 
			
		||||
			"Code block, CodeFences=false",
 | 
			
		||||
			func(conf *markup_config.Config) {
 | 
			
		||||
				withBlockAttributes(conf)
 | 
			
		||||
				conf.Highlight.CodeFences = false
 | 
			
		||||
			},
 | 
			
		||||
			"```bash\necho 'foo';\n```\n{.myclass}",
 | 
			
		||||
			"TODO",
 | 
			
		||||
		},*/
 | 
			
		||||
		{
 | 
			
		||||
			"Code block, CodeFences=true",
 | 
			
		||||
			func(conf *markup_config.Config) {
 | 
			
		||||
				withBlockAttributes(conf)
 | 
			
		||||
				conf.Highlight.CodeFences = true
 | 
			
		||||
			},
 | 
			
		||||
			"```bash\necho 'foo';\n````\n{.myclass id=\"myid\"}",
 | 
			
		||||
			"<div class=\"highlight myclass\" id=\"myid\"><pre style",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"Paragraph",
 | 
			
		||||
			withBlockAttributes,
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,11 @@
 | 
			
		||||
package goldmark
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"github.com/spf13/cast"
 | 
			
		||||
 | 
			
		||||
	"github.com/gohugoio/hugo/markup/converter/hooks"
 | 
			
		||||
 | 
			
		||||
	"github.com/yuin/goldmark"
 | 
			
		||||
@@ -135,13 +138,41 @@ func (r *hookedRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer)
 | 
			
		||||
	reg.Register(ast.KindHeading, r.renderHeading)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// https://github.com/yuin/goldmark/blob/b611cd333a492416b56aa8d94b04a67bf0096ab2/renderer/html/html.go#L404
 | 
			
		||||
func (r *hookedRenderer) RenderAttributes(w util.BufWriter, node ast.Node) {
 | 
			
		||||
	for _, attr := range node.Attributes() {
 | 
			
		||||
func (r *hookedRenderer) renderAttributesForNode(w util.BufWriter, node ast.Node) {
 | 
			
		||||
	renderAttributes(w, false, node.Attributes()...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
 | 
			
		||||
	// Attributes with special meaning that does not make sense to render in HTML.
 | 
			
		||||
	attributeExcludes = map[string]bool{
 | 
			
		||||
		"linenos":     true,
 | 
			
		||||
		"hl_lines":    true,
 | 
			
		||||
		"linenostart": true,
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func renderAttributes(w util.BufWriter, skipClass bool, attributes ...ast.Attribute) {
 | 
			
		||||
	for _, attr := range attributes {
 | 
			
		||||
		if skipClass && bytes.Equal(attr.Name, []byte("class")) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if attributeExcludes[string(attr.Name)] {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		_, _ = w.WriteString(" ")
 | 
			
		||||
		_, _ = w.Write(attr.Name)
 | 
			
		||||
		_, _ = w.WriteString(`="`)
 | 
			
		||||
		_, _ = w.Write(util.EscapeHTML(attr.Value.([]byte)))
 | 
			
		||||
 | 
			
		||||
		switch v := attr.Value.(type) {
 | 
			
		||||
		case []byte:
 | 
			
		||||
			_, _ = w.Write(util.EscapeHTML(v))
 | 
			
		||||
		default:
 | 
			
		||||
			w.WriteString(cast.ToString(v))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		_ = w.WriteByte('"')
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -282,7 +313,7 @@ func (r *hookedRenderer) renderDefaultHeading(w util.BufWriter, source []byte, n
 | 
			
		||||
		_, _ = w.WriteString("<h")
 | 
			
		||||
		_ = w.WriteByte("0123456"[n.Level])
 | 
			
		||||
		if n.Attributes() != nil {
 | 
			
		||||
			r.RenderAttributes(w, node)
 | 
			
		||||
			r.renderAttributesForNode(w, node)
 | 
			
		||||
		}
 | 
			
		||||
		_ = w.WriteByte('>')
 | 
			
		||||
	} else {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user