// 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 }