|
|
@ -16,6 +16,7 @@ import ( |
|
|
|
"code.gitea.io/gitea/modules/setting" |
|
|
|
"code.gitea.io/gitea/modules/setting" |
|
|
|
giteautil "code.gitea.io/gitea/modules/util" |
|
|
|
giteautil "code.gitea.io/gitea/modules/util" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/microcosm-cc/bluemonday/css" |
|
|
|
"github.com/yuin/goldmark/ast" |
|
|
|
"github.com/yuin/goldmark/ast" |
|
|
|
east "github.com/yuin/goldmark/extension/ast" |
|
|
|
east "github.com/yuin/goldmark/extension/ast" |
|
|
|
"github.com/yuin/goldmark/parser" |
|
|
|
"github.com/yuin/goldmark/parser" |
|
|
@ -178,6 +179,11 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa |
|
|
|
v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInDocuments) |
|
|
|
v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInDocuments) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
case *ast.CodeSpan: |
|
|
|
|
|
|
|
colorContent := n.Text(reader.Source()) |
|
|
|
|
|
|
|
if css.ColorHandler(strings.ToLower(string(colorContent))) { |
|
|
|
|
|
|
|
v.AppendChild(v, NewColorPreview(colorContent)) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return ast.WalkContinue, nil |
|
|
|
return ast.WalkContinue, nil |
|
|
|
}) |
|
|
|
}) |
|
|
@ -266,10 +272,43 @@ func (r *HTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { |
|
|
|
reg.Register(KindDetails, r.renderDetails) |
|
|
|
reg.Register(KindDetails, r.renderDetails) |
|
|
|
reg.Register(KindSummary, r.renderSummary) |
|
|
|
reg.Register(KindSummary, r.renderSummary) |
|
|
|
reg.Register(KindIcon, r.renderIcon) |
|
|
|
reg.Register(KindIcon, r.renderIcon) |
|
|
|
|
|
|
|
reg.Register(ast.KindCodeSpan, r.renderCodeSpan) |
|
|
|
reg.Register(KindTaskCheckBoxListItem, r.renderTaskCheckBoxListItem) |
|
|
|
reg.Register(KindTaskCheckBoxListItem, r.renderTaskCheckBoxListItem) |
|
|
|
reg.Register(east.KindTaskCheckBox, r.renderTaskCheckBox) |
|
|
|
reg.Register(east.KindTaskCheckBox, r.renderTaskCheckBox) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// renderCodeSpan renders CodeSpan elements (like goldmark upstream does) but also renders ColorPreview elements.
|
|
|
|
|
|
|
|
// See #21474 for reference
|
|
|
|
|
|
|
|
func (r *HTMLRenderer) renderCodeSpan(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { |
|
|
|
|
|
|
|
if entering { |
|
|
|
|
|
|
|
if n.Attributes() != nil { |
|
|
|
|
|
|
|
_, _ = w.WriteString("<code") |
|
|
|
|
|
|
|
html.RenderAttributes(w, n, html.CodeAttributeFilter) |
|
|
|
|
|
|
|
_ = w.WriteByte('>') |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
_, _ = w.WriteString("<code>") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for c := n.FirstChild(); c != nil; c = c.NextSibling() { |
|
|
|
|
|
|
|
switch v := c.(type) { |
|
|
|
|
|
|
|
case *ast.Text: |
|
|
|
|
|
|
|
segment := v.Segment |
|
|
|
|
|
|
|
value := segment.Value(source) |
|
|
|
|
|
|
|
if bytes.HasSuffix(value, []byte("\n")) { |
|
|
|
|
|
|
|
r.Writer.RawWrite(w, value[:len(value)-1]) |
|
|
|
|
|
|
|
r.Writer.RawWrite(w, []byte(" ")) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
r.Writer.RawWrite(w, value) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
case *ColorPreview: |
|
|
|
|
|
|
|
_, _ = w.WriteString(fmt.Sprintf(`<span class="color-preview" style="background-color: %v"></span>`, string(v.Color))) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return ast.WalkSkipChildren, nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_, _ = w.WriteString("</code>") |
|
|
|
|
|
|
|
return ast.WalkContinue, nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (r *HTMLRenderer) renderDocument(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { |
|
|
|
func (r *HTMLRenderer) renderDocument(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { |
|
|
|
n := node.(*ast.Document) |
|
|
|
n := node.(*ast.Document) |
|
|
|
|
|
|
|
|
|
|
|