Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
3.4 KiB
163 lines
3.4 KiB
// 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 |
|
}
|
|
|