forked from NYANDEV/forgejo
Use markdown frontmatter to provide Table of contents, language and frontmatter rendering (#11047)
* 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
This commit is contained in:
parent
d3fc9c08c8
commit
812cfd0ad9
10 changed files with 509 additions and 16 deletions
163
modules/markup/markdown/renderconfig.go
Normal file
163
modules/markup/markdown/renderconfig.go
Normal file
|
@ -0,0 +1,163 @@
|
|||
// 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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue