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.

83 lines
2.4 KiB

  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package markup
  5. import (
  6. "path/filepath"
  7. "strings"
  8. )
  9. // Parser defines an interface for parsering markup file to HTML
  10. type Parser interface {
  11. Name() string // markup format name
  12. Extensions() []string
  13. Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte
  14. }
  15. var (
  16. parsers = make(map[string]Parser)
  17. )
  18. // RegisterParser registers a new markup file parser
  19. func RegisterParser(parser Parser) {
  20. for _, ext := range parser.Extensions() {
  21. parsers[strings.ToLower(ext)] = parser
  22. }
  23. }
  24. // Render renders markup file to HTML with all specific handling stuff.
  25. func Render(filename string, rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
  26. return render(filename, rawBytes, urlPrefix, metas, false)
  27. }
  28. func render(filename string, rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte {
  29. extension := strings.ToLower(filepath.Ext(filename))
  30. if parser, ok := parsers[extension]; ok {
  31. return parser.Render(rawBytes, urlPrefix, metas, isWiki)
  32. }
  33. return nil
  34. }
  35. // RenderString renders Markdown to HTML with special links and returns string type.
  36. func RenderString(filename string, raw, urlPrefix string, metas map[string]string) string {
  37. return string(render(filename, []byte(raw), urlPrefix, metas, false))
  38. }
  39. // RenderWiki renders markdown wiki page to HTML and return HTML string
  40. func RenderWiki(filename string, rawBytes []byte, urlPrefix string, metas map[string]string) string {
  41. return string(render(filename, rawBytes, urlPrefix, metas, true))
  42. }
  43. // Type returns if markup format via the filename
  44. func Type(filename string) string {
  45. extension := strings.ToLower(filepath.Ext(filename))
  46. if parser, ok := parsers[extension]; ok {
  47. return parser.Name()
  48. }
  49. return ""
  50. }
  51. // ReadmeFileType reports whether name looks like a README file
  52. // based on its name and find the parser via its ext name
  53. func ReadmeFileType(name string) (string, bool) {
  54. if IsReadmeFile(name) {
  55. return Type(name), true
  56. }
  57. return "", false
  58. }
  59. // IsReadmeFile reports whether name looks like a README file
  60. // based on its name.
  61. func IsReadmeFile(name string) bool {
  62. if len(name) < 6 {
  63. return false
  64. }
  65. name = strings.ToLower(name)
  66. if len(name) == 6 {
  67. return name == "readme"
  68. }
  69. return name[:7] == "readme."
  70. }