文章目錄
- 工具功能亮點
- 1.核心實現解析
- 1. 剪貼板交互
- 2. HTML檢測與提取
- 3. 轉換規則設計
- 2. 完整代碼
在日常工作中,我們經常遇到需要將網頁表格快速轉換為Markdown格式的場景。無論是文檔編寫、知識整理還是數據遷移,手動轉換既耗時又容易出錯。本文將介紹一個基于Go語言開發的輕量級工具,它能自動從剪貼板提取HTML表格并轉換為Markdown格式。
工具功能亮點
- 一鍵轉換:直接讀取剪貼板中的HTML內容
- 智能識別:自動檢測并提取首個HTML表格
- 格式優化:保留表格結構并添加Markdown語法
- 無縫銜接:結果自動寫回剪貼板
1.核心實現解析
1. 剪貼板交互
// 讀取剪貼板內容
content, err := clipboard.ReadAll()// 將結果寫回剪貼板
err = clipboard.WriteAll(markdown)
使用atotto/clipboard
庫實現跨平臺剪貼板操作,無需文件中間步驟。
2. HTML檢測與提取
func isHTML(s string) bool {return strings.Contains(s, "<table") || strings.Contains(s, "<tr")
}func extractFirstTable(html string) string {start := strings.Index(html, "<table")end := strings.Index(html[start:], "</table>")return html[start:start+end+8] // 截取完整table標簽
}
通過簡單高效的字符串掃描定位表格位置,避免復雜解析。
3. 轉換規則設計
converter.AddRules(md.Rule{Filter: []string{"table", "tr", "td", "th"},Replacement: func(content string, selec *goquery.Selection) *string {if selec.Is("tr") {return md.String("|" + content + "|\n")}if selec.Is("td") {return md.String(strings.TrimSpace(content) + "|")}// 其他元素處理...}
})
關鍵轉換邏輯:
tr
轉換為行:|內容|
td/th
轉換為單元格:內容|
- 自動添加表頭分隔線:
|---|---|
2. 完整代碼
package mainimport ("fmt""log""os""strings"md "github.com/JohannesKaufmann/html-to-markdown""github.com/PuerkitoBio/goquery""github.com/atotto/clipboard"
)func main() {// 讀取剪貼板內容content, err := clipboard.ReadAll()if err != nil {log.Fatal("讀取剪貼板失敗:", err)}// 檢查是否為HTML內容if !isHTML(content) {fmt.Println("剪貼板內容不是HTML格式")os.Exit(0)}// 提取第一個表格tableHTML, err := extractFirstTable(content)if err != nil {log.Fatal("提取表格失敗:", err)}if tableHTML == "" {fmt.Println("未找到HTML表格")os.Exit(0)}// 轉換為Markdownconverter := md.NewConverter("", true, nil)// 添加表格轉換規則converter.AddRules(md.Rule{Filter: []string{"table", "tr", "td", "th"},Replacement: func(content string, selec *goquery.Selection, opt *md.Options) *string {if selec.Is("table") {// 添加表頭分隔線rows := strings.Split(strings.TrimSpace(content), "\n")if len(rows) > 1 {header := rows[0]cols := strings.Count(header, "|") - 1separator := "|" + strings.Repeat("---|", cols)// 合并所有行,確保每行數據單獨顯示content = strings.Join(append([]string{header, separator}, rows[1:]...), "\n") + "\n"}return &content}if selec.Is("tr") {content = "|" + strings.TrimRight(content, "|") + "|\n"return &content}if selec.Is("th") || selec.Is("td") {content = strings.ReplaceAll(content, "\n", "<br>")content = strings.TrimSpace(content) + "|"return &content}return nil},},)markdown, err := converter.ConvertString(tableHTML)if err != nil {log.Fatal("轉換Markdown失敗:", err)}// 輸出結果到控制臺fmt.Println("轉換后的Markdown表格:")fmt.Println(markdown)// 將結果寫入剪貼板err = clipboard.WriteAll(markdown)if err != nil {log.Fatal("寫入剪貼板失敗:", err)}fmt.Println("已成功將Markdown表格寫入剪貼板")
}// isHTML 檢查字符串是否是HTML格式
func isHTML(s string) bool {return strings.Contains(strings.ToLower(s), "<html") ||strings.Contains(strings.ToLower(s), "<table") ||strings.Contains(strings.ToLower(s), "<tr") ||strings.Contains(strings.ToLower(s), "<td")
}// extractFirstTable 從HTML中提取第一個表格
func extractFirstTable(html string) (string, error) {// 簡單的提取邏輯,實際應用中可能需要更復雜的HTML解析start := strings.Index(strings.ToLower(html), "<table")if start == -1 {return "", nil}end := strings.Index(strings.ToLower(html[start:]), "</table>")if end == -1 {return "", nil}return html[start : start+end+8], nil // +8 是 </table> 的長度
}