github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/markup/markdown/renderconfig.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package markdown 7 8 import ( 9 "fmt" 10 "strings" 11 12 "github.com/yuin/goldmark/ast" 13 east "github.com/yuin/goldmark/extension/ast" 14 "gopkg.in/yaml.v2" 15 ) 16 17 // RenderConfig represents rendering configuration for this file 18 type RenderConfig struct { 19 Meta string 20 Icon string 21 TOC bool 22 Lang string 23 } 24 25 // ToRenderConfig converts a yaml.MapSlice to a RenderConfig 26 func (rc *RenderConfig) ToRenderConfig(meta yaml.MapSlice) { 27 if meta == nil { 28 return 29 } 30 found := false 31 var giteaMetaControl yaml.MapItem 32 for _, item := range meta { 33 strKey, ok := item.Key.(string) 34 if !ok { 35 continue 36 } 37 strKey = strings.TrimSpace(strings.ToLower(strKey)) 38 switch strKey { 39 case "gitea": 40 giteaMetaControl = item 41 found = true 42 case "include_toc": 43 val, ok := item.Value.(bool) 44 if !ok { 45 continue 46 } 47 rc.TOC = val 48 case "lang": 49 val, ok := item.Value.(string) 50 if !ok { 51 continue 52 } 53 val = strings.TrimSpace(val) 54 if len(val) == 0 { 55 continue 56 } 57 rc.Lang = val 58 } 59 } 60 61 if found { 62 switch v := giteaMetaControl.Value.(type) { 63 case string: 64 switch v { 65 case "none": 66 rc.Meta = "none" 67 case "table": 68 rc.Meta = "table" 69 default: // "details" 70 rc.Meta = "details" 71 } 72 case yaml.MapSlice: 73 for _, item := range v { 74 strKey, ok := item.Key.(string) 75 if !ok { 76 continue 77 } 78 strKey = strings.TrimSpace(strings.ToLower(strKey)) 79 switch strKey { 80 case "meta": 81 val, ok := item.Value.(string) 82 if !ok { 83 continue 84 } 85 switch strings.TrimSpace(strings.ToLower(val)) { 86 case "none": 87 rc.Meta = "none" 88 case "table": 89 rc.Meta = "table" 90 default: // "details" 91 rc.Meta = "details" 92 } 93 case "details_icon": 94 val, ok := item.Value.(string) 95 if !ok { 96 continue 97 } 98 rc.Icon = strings.TrimSpace(strings.ToLower(val)) 99 case "include_toc": 100 val, ok := item.Value.(bool) 101 if !ok { 102 continue 103 } 104 rc.TOC = val 105 case "lang": 106 val, ok := item.Value.(string) 107 if !ok { 108 continue 109 } 110 val = strings.TrimSpace(val) 111 if len(val) == 0 { 112 continue 113 } 114 rc.Lang = val 115 } 116 } 117 } 118 } 119 } 120 121 func (rc *RenderConfig) toMetaNode(meta yaml.MapSlice) ast.Node { 122 switch rc.Meta { 123 case "table": 124 return metaToTable(meta) 125 case "details": 126 return metaToDetails(meta, rc.Icon) 127 default: 128 return nil 129 } 130 } 131 132 func metaToTable(meta yaml.MapSlice) ast.Node { 133 table := east.NewTable() 134 alignments := []east.Alignment{} 135 for range meta { 136 alignments = append(alignments, east.AlignNone) 137 } 138 row := east.NewTableRow(alignments) 139 for _, item := range meta { 140 cell := east.NewTableCell() 141 cell.AppendChild(cell, ast.NewString([]byte(fmt.Sprintf("%v", item.Key)))) 142 row.AppendChild(row, cell) 143 } 144 table.AppendChild(table, east.NewTableHeader(row)) 145 146 row = east.NewTableRow(alignments) 147 for _, item := range meta { 148 cell := east.NewTableCell() 149 cell.AppendChild(cell, ast.NewString([]byte(fmt.Sprintf("%v", item.Value)))) 150 row.AppendChild(row, cell) 151 } 152 table.AppendChild(table, row) 153 return table 154 } 155 156 func metaToDetails(meta yaml.MapSlice, icon string) ast.Node { 157 details := NewDetails() 158 summary := NewSummary() 159 summary.AppendChild(summary, NewIcon(icon)) 160 details.AppendChild(details, summary) 161 details.AppendChild(details, metaToTable(meta)) 162 163 return details 164 }