本站源代码
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

106 lines
2.6KB

  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 external
  5. import (
  6. "bytes"
  7. "io"
  8. "io/ioutil"
  9. "os"
  10. "os/exec"
  11. "runtime"
  12. "strings"
  13. "code.gitea.io/gitea/modules/log"
  14. "code.gitea.io/gitea/modules/markup"
  15. "code.gitea.io/gitea/modules/setting"
  16. )
  17. // RegisterParsers registers all supported third part parsers according settings
  18. func RegisterParsers() {
  19. for _, parser := range setting.ExternalMarkupParsers {
  20. if parser.Enabled && parser.Command != "" && len(parser.FileExtensions) > 0 {
  21. markup.RegisterParser(&Parser{parser})
  22. }
  23. }
  24. }
  25. // Parser implements markup.Parser for external tools
  26. type Parser struct {
  27. setting.MarkupParser
  28. }
  29. // Name returns the external tool name
  30. func (p *Parser) Name() string {
  31. return p.MarkupName
  32. }
  33. // Extensions returns the supported extensions of the tool
  34. func (p *Parser) Extensions() []string {
  35. return p.FileExtensions
  36. }
  37. func envMark(envName string) string {
  38. if runtime.GOOS == "windows" {
  39. return "%" + envName + "%"
  40. }
  41. return "$" + envName
  42. }
  43. // Render renders the data of the document to HTML via the external tool.
  44. func (p *Parser) Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte {
  45. var (
  46. bs []byte
  47. buf = bytes.NewBuffer(bs)
  48. rd = bytes.NewReader(rawBytes)
  49. urlRawPrefix = strings.Replace(urlPrefix, "/src/", "/raw/", 1)
  50. command = strings.NewReplacer(envMark("GITEA_PREFIX_SRC"), urlPrefix,
  51. envMark("GITEA_PREFIX_RAW"), urlRawPrefix).Replace(p.Command)
  52. commands = strings.Fields(command)
  53. args = commands[1:]
  54. )
  55. if p.IsInputFile {
  56. // write to temp file
  57. f, err := ioutil.TempFile("", "gitea_input")
  58. if err != nil {
  59. log.Error("%s create temp file when rendering %s failed: %v", p.Name(), p.Command, err)
  60. return []byte("")
  61. }
  62. defer os.Remove(f.Name())
  63. _, err = io.Copy(f, rd)
  64. if err != nil {
  65. f.Close()
  66. log.Error("%s write data to temp file when rendering %s failed: %v", p.Name(), p.Command, err)
  67. return []byte("")
  68. }
  69. err = f.Close()
  70. if err != nil {
  71. log.Error("%s close temp file when rendering %s failed: %v", p.Name(), p.Command, err)
  72. return []byte("")
  73. }
  74. args = append(args, f.Name())
  75. }
  76. cmd := exec.Command(commands[0], args...)
  77. cmd.Env = append(
  78. os.Environ(),
  79. "GITEA_PREFIX_SRC="+urlPrefix,
  80. "GITEA_PREFIX_RAW="+urlRawPrefix,
  81. )
  82. if !p.IsInputFile {
  83. cmd.Stdin = rd
  84. }
  85. cmd.Stdout = buf
  86. if err := cmd.Run(); err != nil {
  87. log.Error("%s render run command %s %v failed: %v", p.Name(), commands[0], args, err)
  88. return []byte("")
  89. }
  90. return buf.Bytes()
  91. }
上海开阖软件有限公司 沪ICP备12045867号-1