golang实现HTML转Markdown格式转换插件库html-to-markdown的使用
Golang实现HTML转Markdown格式转换插件库html-to-markdown的使用
html-to-markdown是一个强大的HTML转Markdown转换器,可以将HTML(甚至是整个网站)转换为干净、可读的Markdown格式。它支持复杂的格式化、可定制的选项和插件,可以完全控制转换过程。
主要特性
- 粗体和斜体:支持粗体和斜体,甚至可以在单个单词内使用
- 列表:处理有序和无序列表,支持完整嵌套
- 引用块:引用块可以包含其他元素,完美支持嵌套引用
- 内联代码和代码块:正确处理反引号和多行代码块,保留代码结构
- 链接和图片:正确格式化多行链接,在需要时添加空白行转义
- 智能转义:仅在必要时转义特殊字符,避免意外的Markdown渲染
- 移除/保留HTML:选择删除或保留特定的HTML标签,完全控制输出
- 插件:轻松扩展插件,或创建自定义插件以增强功能
- 表格插件:转换表格,支持对齐、行跨度和列跨度
Golang库使用
安装
go get -u github.com/JohannesKaufmann/html-to-markdown/v2
基本用法
package main
import (
"fmt"
"log"
htmltomarkdown "github.com/JohannesKaufmann/html-to-markdown/v2"
)
func main() {
input := `<strong>Bold Text</strong>`
markdown, err := htmltomarkdown.ConvertString(input)
if err != nil {
log.Fatal(err)
}
fmt.Println(markdown)
// Output: **Bold Text**
}
使用WithDomain转换相对链接为绝对链接
package main
import (
"fmt"
"log"
htmltomarkdown "github.com/JohannesKaufmann/html-to-markdown/v2"
"github.com/JohannesKaufmann/html-to-markdown/v2/converter"
)
func main() {
input := `<img src="/assets/image.png" />`
markdown, err := htmltomarkdown.ConvertString(
input,
converter.WithDomain("https://example.com"),
)
if err != nil {
log.Fatal(err)
}
fmt.Println(markdown)
// Output: 
}
高级用法(更多控制)
package main
import (
"fmt"
"log"
"github.com/JohannesKaufmann/html-to-markdown/v2/converter"
"github.com/JohannesKaufmann/html-to-markdown/v2/plugin/base"
"github.com/JohannesKaufmann/html-to-markdown/v2/plugin/commonmark"
)
func main() {
input := `<strong>Bold Text</strong>`
conv := converter.NewConverter(
converter.WithPlugins(
base.NewBasePlugin(),
commonmark.NewCommonmarkPlugin(
commonmark.WithStrongDelimiter("__"),
// ...additional configurations for the plugin
),
// ...additional plugins (e.g. table)
),
)
markdown, err := conv.ConvertString(input)
if err != nil {
log.Fatal(err)
}
fmt.Println(markdown)
// Output: __Bold Text__
}
标签类型和折叠
你可以指定在转换过程中如何处理不同的HTML标签:
conv.Register.TagType("nav", converter.TagTypeRemove, converter.PriorityStandard)
conv.Register.RendererFor("b", converter.TagTypeInline, base.RenderAsHTML, converter.PriorityEarly)
conv.Register.RendererFor("article", converter.TagTypeBlock, base.RenderAsHTMLWrapper, converter.PriorityStandard)
插件系统
已发布的插件
名称 | 描述 |
---|---|
Base | 实现基本共享功能(例如删除节点) |
Commonmark | 根据Commonmark规范实现Markdown |
Strikethrough | 将<strike> , <s> 和<del> 转换为~~ 语法 |
Table | 根据GitHub Flavored Markdown规范实现表格 |
编写插件
- 编写你的逻辑并注册它
- (可选)将你的逻辑打包成一个插件并发布
CLI命令行使用
安装
# Homebrew安装
brew install JohannesKaufmann/tap/html2markdown
# 通过Go安装
go install github.com/JohannesKaufmann/html-to-markdown/v2/cli/html2markdown@latest
基本用法
$ echo "<strong>important</strong>" | html2markdown
**important**
$ curl --no-progress-meter http://example.com | html2markdown
# Example Domain
This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.
[More information...](https://www.iana.org/domains/example)
$ html2markdown --input file.html --output file.md
$ html2markdown --input "src/*.html" --output "dist/"
常见问题
扩展插件
- 需要自定义逻辑?编写你自己的代码然后注册它
- 如果你认为你的逻辑对其他人也有用,可以将其打包成一个插件
安全问题
这个库生成的Markdown是可读的,可以由人类修改。一旦你将这个Markdown转换回HTML(例如使用goldmark或blackfriday),你需要小心恶意内容。这个库不会清理不受信任的内容。在浏览器中显示HTML之前,请使用HTML清理器(如bluemonday)。
并发使用
你可以从(多个)goroutine中使用Converter
。内部使用互斥锁,并且有一个测试来验证这种行为。
测试
你不必担心破坏转换器,因为有许多"Golden File"测试:将你的有问题的HTML片段添加到testdata
文件夹中的一个.in.html
文件中。然后运行go test -update
,并查看GIT中哪些.out.md
文件发生了变化。
更多关于golang实现HTML转Markdown格式转换插件库html-to-markdown的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang实现HTML转Markdown格式转换插件库html-to-markdown的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用html-to-markdown实现HTML转Markdown
在Go语言中,可以使用github.com/JohannesKaufmann/html-to-markdown
库来实现HTML到Markdown的转换。这个库提供了简单易用的API,能够将HTML内容转换为Markdown格式。
安装
首先需要安装该库:
go get github.com/JohannesKaufmann/html-to-markdown
基本使用
下面是一个基本的使用示例:
package main
import (
"fmt"
"log"
md "github.com/JohannesKaufmann/html-to-markdown"
)
func main() {
html := `
<h1>标题1</h1>
<h2>标题2</h2>
<p>这是一个段落,包含<strong>加粗</strong>和<em>斜体</em>文本。</p>
<ul>
<li>列表项1</li>
<li>列表项2</li>
</ul>
<a href="https://example.com">链接</a>
`
converter := md.NewConverter("", true, nil)
markdown, err := converter.ConvertString(html)
if err != nil {
log.Fatal(err)
}
fmt.Println(markdown)
}
输出结果:
# 标题1
## 标题2
这是一个段落,包含**加粗**和*斜体*文本。
- 列表项1
- 列表项2
[链接](https://example.com)
高级配置
自定义转换规则
你可以自定义HTML元素的转换规则:
converter := md.NewConverter("", true, nil)
// 添加自定义规则
converter.AddRules(
// 转换<blockquote>标签
md.Rule{
Filter: []string{"blockquote"},
Replacement: func(content string, selec *goquery.Selection, opt *md.Options) *string {
// 在每个blockquote行前添加>
lines := strings.Split(content, "\n")
for i := range lines {
if lines[i] != "" {
lines[i] = "> " + lines[i]
}
}
content = strings.Join(lines, "\n")
return &content
},
},
)
处理特定属性
converter := md.NewConverter("", true, nil)
// 处理img标签的title属性
converter.AddRules(
md.Rule{
Filter: []string{"img"},
Replacement: func(content string, selec *goquery.Selection, opt *md.Options) *string {
src := selec.AttrOr("src", "")
alt := selec.AttrOr("alt", "")
title := selec.AttrOr("title", "")
var result string
if title != "" {
result = fmt.Sprintf("", alt, src, title)
} else {
result = fmt.Sprintf("", alt, src)
}
return &result
},
},
)
忽略特定元素
converter := md.NewConverter("", true, nil)
// 忽略script和style标签
converter.AddRules(
md.Rule{
Filter: []string{"script", "style"},
Replacement: func(content string, selec *goquery.Selection, opt *md.Options) *string {
return nil // 返回nil表示忽略该元素
},
},
)
完整示例
下面是一个完整的示例,展示如何处理更复杂的HTML:
package main
import (
"fmt"
"log"
"strings"
md "github.com/JohannesKaufmann/html-to-markdown"
"github.com/PuerkitoBio/goquery"
)
func main() {
html := `
<div class="article">
<h1>文章标题</h1>
<div class="author">作者: 张三</div>
<p>这是第一段内容。</p>
<p>这是第二段内容,包含<a href="https://example.com">链接</a>和<code>代码</code>。</p>
<pre><code class="language-go">package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}</code></pre>
<table>
<tr><th>姓名</th><th>年龄</th></tr>
<tr><td>张三</td><td>25</td></tr>
</table>
</div>
`
converter := md.NewConverter("", true, nil)
// 添加自定义规则
converter.AddRules(
// 处理表格
md.Rule{
Filter: []string{"table"},
Replacement: func(content string, selec *goquery.Selection, opt *md.Options) *string {
var header []string
var rows [][]string
// 处理表头
selec.Find("tr").Each(func(i int, tr *goquery.Selection) {
if i == 0 { // 第一行是表头
tr.Find("th").Each(func(j int, th *goquery.Selection) {
header = append(header, strings.TrimSpace(th.Text()))
})
return
}
// 处理数据行
var row []string
tr.Find("td").Each(func(j int, td *goquery.Selection) {
row = append(row, strings.TrimSpace(td.Text()))
})
if len(row) > 0 {
rows = append(rows, row)
}
})
if len(header) == 0 || len(rows) == 0 {
return nil
}
// 构建Markdown表格
var builder strings.Builder
// 表头
builder.WriteString("| " + strings.Join(header, " | ") + " |\n")
// 分隔线
builder.WriteString("|")
for range header {
builder.WriteString(" --- |")
}
builder.WriteString("\n")
// 数据行
for _, row := range rows {
builder.WriteString("| " + strings.Join(row, " | ") + " |\n")
}
result := builder.String()
return &result
},
},
)
markdown, err := converter.ConvertString(html)
if err != nil {
log.Fatal(err)
}
fmt.Println(markdown)
}
注意事项
- 该库依赖
github.com/PuerkitoBio/goquery
来解析HTML - 对于复杂的HTML结构,可能需要添加自定义规则
- 转换结果可能不完全符合你的预期,需要根据需求调整规则
- 某些HTML5元素可能没有默认的转换规则
这个库提供了灵活的API,你可以根据需要扩展或修改转换规则,以获得最佳的Markdown输出效果。