gitea源码

block_renderer.go 2.1KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package math
  4. import (
  5. "html/template"
  6. "code.gitea.io/gitea/modules/markup/internal"
  7. giteaUtil "code.gitea.io/gitea/modules/util"
  8. gast "github.com/yuin/goldmark/ast"
  9. "github.com/yuin/goldmark/renderer"
  10. "github.com/yuin/goldmark/util"
  11. )
  12. // Block render output:
  13. // <pre class="code-block is-loading"><code class="language-math display">...</code></pre>
  14. //
  15. // Keep in mind that there is another "code block" render in "func (r *GlodmarkRender) highlightingRenderer"
  16. // "highlightingRenderer" outputs the math block with extra "chroma" class:
  17. // <pre class="code-block is-loading"><code class="chroma language-math display">...</code></pre>
  18. //
  19. // Special classes:
  20. // * "is-loading": show a loading indicator
  21. // * "display": used by JS to decide to render as a block, otherwise render as inline
  22. // BlockRenderer represents a renderer for math Blocks
  23. type BlockRenderer struct {
  24. renderInternal *internal.RenderInternal
  25. }
  26. // NewBlockRenderer creates a new renderer for math Blocks
  27. func NewBlockRenderer(renderInternal *internal.RenderInternal) renderer.NodeRenderer {
  28. return &BlockRenderer{renderInternal: renderInternal}
  29. }
  30. // RegisterFuncs registers the renderer for math Blocks
  31. func (r *BlockRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
  32. reg.Register(KindBlock, r.renderBlock)
  33. }
  34. func (r *BlockRenderer) writeLines(w util.BufWriter, source []byte, n gast.Node) {
  35. l := n.Lines().Len()
  36. for i := range l {
  37. line := n.Lines().At(i)
  38. _, _ = w.Write(util.EscapeHTML(line.Value(source)))
  39. }
  40. }
  41. func (r *BlockRenderer) renderBlock(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
  42. n := node.(*Block)
  43. if entering {
  44. codeHTML := giteaUtil.Iif[template.HTML](n.Inline, "", `<pre class="code-block is-loading">`) + `<code class="language-math display">`
  45. _, _ = w.WriteString(string(r.renderInternal.ProtectSafeAttrs(codeHTML)))
  46. r.writeLines(w, source, n)
  47. } else {
  48. _, _ = w.WriteString(`</code>` + giteaUtil.Iif(n.Inline, "", `</pre>`) + "\n")
  49. }
  50. return gast.WalkContinue, nil
  51. }