Golang实现markdown转html

2025-09-12

Golang实现markdown转html

演示网站:gofly.v1kf.com
我的微信:llike620
我的微信

在Go语言中实现Markdown转HTML可以使用一些成熟的第三方库。以下是几种常见的实现方式:

1. 使用 blackfriday 库(最流行的Markdown解析库)

package main

import (
	"fmt"
	"github.com/russross/blackfriday/v2"
)

func markdownToHTML(markdown string) string {
	// 基本转换
	html := blackfriday.Run([]byte(markdown))
	return string(html)
}

func main() {
	markdown := `# 标题
这是**加粗**文字
- 列表项1
- 列表项2

https://example.com`
	
	html := markdownToHTML(markdown)
	fmt.Println(html)
}

2. 使用 goldmark 库(更现代、可扩展性更强)

package main

import (
	"bytes"
	"fmt"
	"github.com/yuin/goldmark"
)

func markdownToHTML(markdown string) (string, error) {
	var buf bytes.Buffer
	md := goldmark.New()
	if err := md.Convert([]byte(markdown), &buf); err != nil {
		return "", err
	}
	return buf.String(), nil
}

func main() {
	markdown := `## Goldmark示例
*斜体* 和 **加粗**

代码块:
` + "```go\nfmt.Println(\"Hello\")\n```"

	html, err := markdownToHTML(markdown)
	if err != nil {
		fmt.Println("转换失败:", err)
		return
	}
	fmt.Println(html)
}

3. 使用支持扩展的 goldmark 实现(带语法高亮)

package main

import (
	"bytes"
	"fmt"
	"github.com/yuin/goldmark"
	"github.com/yuin/goldmark/extension"
	"github.com/yuin/goldmark/parser"
	"github.com/yuin/goldmark/renderer/html"
)

func markdownToHTML(markdown string) (string, error) {
	var buf bytes.Buffer
	
	md := goldmark.New(
		goldmark.WithExtensions(extension.GFM), // GitHub Flavored Markdown
		goldmark.WithParserOptions(
			parser.WithAutoHeadingID(), // 自动生成标题ID
		),
		goldmark.WithRendererOptions(
			html.WithHardWraps(), // 将换行转换为<br>
			html.WithXHTML(),     // 输出XHTML
		),
	)
	
	if err := md.Convert([]byte(markdown), &buf); err != nil {
		return "", err
	}
	return buf.String(), nil
}

func main() {
	markdown := `## 高级功能
表格支持:

| 功能 | 描述 |
|------|------|
| 表格 | 支持GFM表格 |
| 任务列表 | - [x] 完成项目`

	html, err := markdownToHTML(markdown)
	if err != nil {
		fmt.Println("转换失败:", err)
		return
	}
	fmt.Println(html)
}

4. 带语法高亮的完整实现

package main

import (
	"bytes"
	"fmt"
	"github.com/alecthomas/chroma/v2/formatters/html"
	"github.com/yuin/goldmark"
	highlighting "github.com/yuin/goldmark-highlighting/v2"
	"github.com/yuin/goldmark/extension"
	"github.com/yuin/goldmark/parser"
	"github.com/yuin/goldmark/renderer/html"
)

func markdownToHTML(markdown string) (string, error) {
	var buf bytes.Buffer
	
	md := goldmark.New(
		goldmark.WithExtensions(
			extension.GFM,
			extension.Table,
			extension.Strikethrough,
			extension.TaskList,
			extension.Linkify,
			highlighting.NewHighlighting(
				highlighting.WithStyle("github"), // 代码高亮样式
				highlighting.WithFormatOptions(
					html.WithLineNumbers(true), // 显示行号
				),
			),
		),
		goldmark.WithParserOptions(
			parser.WithAutoHeadingID(),
		),
		goldmark.WithRendererOptions(
			html.WithHardWraps(),
			html.WithXHTML(),
		),
	)
	
	if err := md.Convert([]byte(markdown), &buf); err != nil {
		return "", err
	}
	return buf.String(), nil
}

func main() {
	markdown := `# 完整示例
## 代码高亮

` + "```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.Println(\"Hello, World!\")\n}\n```" + `

## 数学公式
支持LaTeX公式: $E=mc^2$`

	html, err := markdownToHTML(markdown)
	if err != nil {
		fmt.Println("转换失败:", err)
		return
	}
	fmt.Println(html)
}

5. 在Web应用中使用的示例

package main

import (
	"github.com/gin-gonic/gin"
	"github.com/yuin/goldmark"
	"net/http"
)

func main() {
	r := gin.Default()
	
	// 配置Markdown转换器
	md := goldmark.New()
	
	r.POST("/markdown", func(c *gin.Context) {
		markdown := c.PostForm("markdown")
		var buf bytes.Buffer
		if err := md.Convert([]byte(markdown), &buf); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		c.JSON(http.StatusOK, gin.H{"html": buf.String()})
	})
	
	r.GET("/", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", nil)
	})
	
	r.Run(":8080")
}

比较几个主要Markdown库:

  1. blackfriday

    • 成熟稳定
    • 性能好
    • 功能相对基础
  2. goldmark

    • 更现代的设计
    • 高度可扩展
    • 支持CommonMark标准
    • 有丰富的扩展生态系统
  3. go-markdown

    • 另一个选择
    • 介于前两者之间

对于大多数现代应用,推荐使用goldmark,因为它有更好的扩展性和对最新Markdown特性的支持。

注意事项:

  1. 如果处理用户输入的Markdown,记得对最终HTML进行消毒,防止XSS攻击
  2. 对于复杂的需求(如自定义渲染),goldmark提供了更多的灵活性
  3. 代码高亮需要额外配置chroma等语法高亮库

希望这些示例能帮助你在Go中实现Markdown到HTML的转换!