gitea源码

convertyaml.go 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package markdown
  4. import (
  5. "strings"
  6. "code.gitea.io/gitea/modules/htmlutil"
  7. "code.gitea.io/gitea/modules/svg"
  8. "github.com/yuin/goldmark/ast"
  9. east "github.com/yuin/goldmark/extension/ast"
  10. "gopkg.in/yaml.v3"
  11. )
  12. func nodeToTable(meta *yaml.Node) ast.Node {
  13. for meta != nil && meta.Kind == yaml.DocumentNode {
  14. meta = meta.Content[0]
  15. }
  16. if meta == nil {
  17. return nil
  18. }
  19. switch meta.Kind {
  20. case yaml.MappingNode:
  21. return mappingNodeToTable(meta)
  22. case yaml.SequenceNode:
  23. return sequenceNodeToTable(meta)
  24. default:
  25. return ast.NewString([]byte(meta.Value))
  26. }
  27. }
  28. func mappingNodeToTable(meta *yaml.Node) ast.Node {
  29. table := east.NewTable()
  30. alignments := make([]east.Alignment, 0, len(meta.Content)/2)
  31. for i := 0; i < len(meta.Content); i += 2 {
  32. alignments = append(alignments, east.AlignNone)
  33. }
  34. headerRow := east.NewTableRow(alignments)
  35. valueRow := east.NewTableRow(alignments)
  36. for i := 0; i < len(meta.Content); i += 2 {
  37. cell := east.NewTableCell()
  38. cell.AppendChild(cell, nodeToTable(meta.Content[i]))
  39. headerRow.AppendChild(headerRow, cell)
  40. if i+1 < len(meta.Content) {
  41. cell = east.NewTableCell()
  42. cell.AppendChild(cell, nodeToTable(meta.Content[i+1]))
  43. valueRow.AppendChild(valueRow, cell)
  44. }
  45. }
  46. table.AppendChild(table, east.NewTableHeader(headerRow))
  47. table.AppendChild(table, valueRow)
  48. return table
  49. }
  50. func sequenceNodeToTable(meta *yaml.Node) ast.Node {
  51. table := east.NewTable()
  52. alignments := []east.Alignment{east.AlignNone}
  53. for _, item := range meta.Content {
  54. row := east.NewTableRow(alignments)
  55. cell := east.NewTableCell()
  56. cell.AppendChild(cell, nodeToTable(item))
  57. row.AppendChild(row, cell)
  58. table.AppendChild(table, row)
  59. }
  60. return table
  61. }
  62. func nodeToDetails(g *ASTTransformer, meta *yaml.Node) ast.Node {
  63. for meta != nil && meta.Kind == yaml.DocumentNode {
  64. meta = meta.Content[0]
  65. }
  66. if meta == nil {
  67. return nil
  68. }
  69. if meta.Kind != yaml.MappingNode {
  70. return nil
  71. }
  72. var keys []string
  73. for i := 0; i < len(meta.Content); i += 2 {
  74. if meta.Content[i].Kind == yaml.ScalarNode {
  75. keys = append(keys, meta.Content[i].Value)
  76. }
  77. }
  78. details := NewDetails()
  79. details.SetAttributeString(g.renderInternal.SafeAttr("class"), g.renderInternal.SafeValue("frontmatter-content"))
  80. summary := NewSummary()
  81. summaryInnerHTML := htmlutil.HTMLFormat("%s %s", svg.RenderHTML("octicon-table", 12), strings.Join(keys, ", "))
  82. summary.AppendChild(summary, NewRawHTML(summaryInnerHTML))
  83. details.AppendChild(details, summary)
  84. details.AppendChild(details, nodeToTable(meta))
  85. return details
  86. }