* Add control for the rendering of the frontmatter * Add control to include a TOC * Add control to set language - allows control of ToC header and CJK glyph choice. Signed-off-by: Andrew Thornton art27@cantab.net
		
			
				
	
	
		
			163 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2020 The Gitea Authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a MIT-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
package markdown
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"github.com/yuin/goldmark/ast"
 | 
						|
	east "github.com/yuin/goldmark/extension/ast"
 | 
						|
	"gopkg.in/yaml.v2"
 | 
						|
)
 | 
						|
 | 
						|
// RenderConfig represents rendering configuration for this file
 | 
						|
type RenderConfig struct {
 | 
						|
	Meta string
 | 
						|
	Icon string
 | 
						|
	TOC  bool
 | 
						|
	Lang string
 | 
						|
}
 | 
						|
 | 
						|
// ToRenderConfig converts a yaml.MapSlice to a RenderConfig
 | 
						|
func (rc *RenderConfig) ToRenderConfig(meta yaml.MapSlice) {
 | 
						|
	if meta == nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	found := false
 | 
						|
	var giteaMetaControl yaml.MapItem
 | 
						|
	for _, item := range meta {
 | 
						|
		strKey, ok := item.Key.(string)
 | 
						|
		if !ok {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		strKey = strings.TrimSpace(strings.ToLower(strKey))
 | 
						|
		switch strKey {
 | 
						|
		case "gitea":
 | 
						|
			giteaMetaControl = item
 | 
						|
			found = true
 | 
						|
		case "include_toc":
 | 
						|
			val, ok := item.Value.(bool)
 | 
						|
			if !ok {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
			rc.TOC = val
 | 
						|
		case "lang":
 | 
						|
			val, ok := item.Value.(string)
 | 
						|
			if !ok {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
			val = strings.TrimSpace(val)
 | 
						|
			if len(val) == 0 {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
			rc.Lang = val
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if found {
 | 
						|
		switch v := giteaMetaControl.Value.(type) {
 | 
						|
		case string:
 | 
						|
			switch v {
 | 
						|
			case "none":
 | 
						|
				rc.Meta = "none"
 | 
						|
			case "table":
 | 
						|
				rc.Meta = "table"
 | 
						|
			default: // "details"
 | 
						|
				rc.Meta = "details"
 | 
						|
			}
 | 
						|
		case yaml.MapSlice:
 | 
						|
			for _, item := range v {
 | 
						|
				strKey, ok := item.Key.(string)
 | 
						|
				if !ok {
 | 
						|
					continue
 | 
						|
				}
 | 
						|
				strKey = strings.TrimSpace(strings.ToLower(strKey))
 | 
						|
				switch strKey {
 | 
						|
				case "meta":
 | 
						|
					val, ok := item.Value.(string)
 | 
						|
					if !ok {
 | 
						|
						continue
 | 
						|
					}
 | 
						|
					switch strings.TrimSpace(strings.ToLower(val)) {
 | 
						|
					case "none":
 | 
						|
						rc.Meta = "none"
 | 
						|
					case "table":
 | 
						|
						rc.Meta = "table"
 | 
						|
					default: // "details"
 | 
						|
						rc.Meta = "details"
 | 
						|
					}
 | 
						|
				case "details_icon":
 | 
						|
					val, ok := item.Value.(string)
 | 
						|
					if !ok {
 | 
						|
						continue
 | 
						|
					}
 | 
						|
					rc.Icon = strings.TrimSpace(strings.ToLower(val))
 | 
						|
				case "include_toc":
 | 
						|
					val, ok := item.Value.(bool)
 | 
						|
					if !ok {
 | 
						|
						continue
 | 
						|
					}
 | 
						|
					rc.TOC = val
 | 
						|
				case "lang":
 | 
						|
					val, ok := item.Value.(string)
 | 
						|
					if !ok {
 | 
						|
						continue
 | 
						|
					}
 | 
						|
					val = strings.TrimSpace(val)
 | 
						|
					if len(val) == 0 {
 | 
						|
						continue
 | 
						|
					}
 | 
						|
					rc.Lang = val
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (rc *RenderConfig) toMetaNode(meta yaml.MapSlice) ast.Node {
 | 
						|
	switch rc.Meta {
 | 
						|
	case "table":
 | 
						|
		return metaToTable(meta)
 | 
						|
	case "details":
 | 
						|
		return metaToDetails(meta, rc.Icon)
 | 
						|
	default:
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func metaToTable(meta yaml.MapSlice) ast.Node {
 | 
						|
	table := east.NewTable()
 | 
						|
	alignments := []east.Alignment{}
 | 
						|
	for range meta {
 | 
						|
		alignments = append(alignments, east.AlignNone)
 | 
						|
	}
 | 
						|
	row := east.NewTableRow(alignments)
 | 
						|
	for _, item := range meta {
 | 
						|
		cell := east.NewTableCell()
 | 
						|
		cell.AppendChild(cell, ast.NewString([]byte(fmt.Sprintf("%v", item.Key))))
 | 
						|
		row.AppendChild(row, cell)
 | 
						|
	}
 | 
						|
	table.AppendChild(table, east.NewTableHeader(row))
 | 
						|
 | 
						|
	row = east.NewTableRow(alignments)
 | 
						|
	for _, item := range meta {
 | 
						|
		cell := east.NewTableCell()
 | 
						|
		cell.AppendChild(cell, ast.NewString([]byte(fmt.Sprintf("%v", item.Value))))
 | 
						|
		row.AppendChild(row, cell)
 | 
						|
	}
 | 
						|
	table.AppendChild(table, row)
 | 
						|
	return table
 | 
						|
}
 | 
						|
 | 
						|
func metaToDetails(meta yaml.MapSlice, icon string) ast.Node {
 | 
						|
	details := NewDetails()
 | 
						|
	summary := NewSummary()
 | 
						|
	summary.AppendChild(summary, NewIcon(icon))
 | 
						|
	details.AppendChild(details, summary)
 | 
						|
	details.AppendChild(details, metaToTable(meta))
 | 
						|
 | 
						|
	return details
 | 
						|
}
 |