赞
踩
使用markdown记录学习笔记,发现markdown删除掉不使用的图片后,只是删除了md文件中对图片的引用,图片依旧保留在文件夹中。
在频繁修改md文件时,不使用的图片会越来越多,占用磁盘空间,所以想把不再使用的图片全部删除。
已经有网友实现了这个功能,我为了锻炼下自己的golang的代码能力,所以就自己又实现了一遍。
推荐一个markdown编辑软件,目前依旧开源免费。markText
首先,通过配置文件提供md文件和img文件存储的目录。配置文件名叫”config.json“
{
"mddir":"your markdown file directory",
"imgdir":"your img file directory"
}
img目录存储md文件中用到的图片。
实现过程如下:
我最熟悉c语言,golang是我最近学习的,所以代码中的C语言的气息会比较浓重,将就着看吧。
package main import ( "bufio" "encoding/json" "fmt" "io" "log" "os" "regexp" "strings" ) type cofigFile struct { MDdir string `json:"mddir"` ImgDir string `json:"imgdir"` } var configForMd cofigFile var mapPngUsedString map[string]int = make(map[string]int) var mapPngAll map[string]int = make(map[string]int) var mdfileList = make([]string, 0) func main() { //获取Markdown文件和img文件存储的路径 getConfigFile("./config.json") //遍历markdown文件夹,找到所有md文件 scanMDdir(configForMd.MDdir) fmt.Println("len(mdfileList):", len(mdfileList)) for index := 0; index < len(mdfileList); index++ { mdfileName := mdfileList[index] fmt.Println("scan mdfile[", index, "]:", configForMd.MDdir+mdfileName) inputFile, inputError := os.Open(configForMd.MDdir + mdfileName) if inputError != nil { fmt.Printf("An error occurred on opening the inputfile\n" + "Does the file exist?\n" + "Have you got acces to it?\n") return // exit the function on error } defer inputFile.Close() inputReader := bufio.NewReader(inputFile) for { inputString, readerError := inputReader.ReadString('\n') //fmt.Printf("The input was: %s", inputString) if readerError == io.EOF { break } // 使用正则表达式,寻找png的路径和文件名, matchStr, _ := regFindImg(inputString) // 将寻找到的在使用的png的文件名记录到map中 storePngUsedfile(matchStr) } } for k, _ := range mapPngUsedString { fmt.Println("used:", k) } // 将img目录下的png文件名记录到mapPngAll中 getPngALL(configForMd.ImgDir) for k, _ := range mapPngAll { fmt.Println("all png:", k) } // 过滤掉没有使用的png图片文件名 filterUnusedPngFile() // 删除掉未使用的png图片 deleteUnusedPng(configForMd.ImgDir) //等待用户输入,以便看到过程中的打印 var temp int fmt.Scanln(&temp) } // 遍历markdown文件夹下,找到所有Markdown文件 func scanMDdir(mddirPath string) { fileinfo, err := os.Open(mddirPath) if err != nil { return } files, err := fileinfo.Readdir(-1) fileinfo.Close() if err != nil { return } for _, file := range files { //fmt.Println("mddir:", file.Name()) if !file.IsDir() && regFindmd(file.Name()) { mdfileList = append(mdfileList, file.Name()) fmt.Println("mdfile:", file.Name()) } } } func regFindmd(filename string) bool { if strings.HasSuffix(filename, ".md") { return true } else { return false } } // 删除掉未使用的png图片 func deleteUnusedPng(imgdir string) { for filename, _ := range mapPngAll { delfinename := imgdir + filename fmt.Println("del file:", delfinename) os.Remove(delfinename) } } // 过滤掉没有使用的png图片文件名 func filterUnusedPngFile() { for allpng, _ := range mapPngAll { if _, ok := mapPngUsedString[allpng]; ok { fmt.Println(allpng, "is used") delete(mapPngAll, allpng) } } } // 将img目录下的png文件名记录到mapPngAll中 func getPngALL(dirpath string) { files, err := os.Open(dirpath) //open the directory to read files in the directory if err != nil { fmt.Println("error opening directory:", err) //print error if directory is not opened return } defer files.Close() //close the directory opened fileInfos, err := files.Readdir(-1) //read the files from the directory if err != nil { fmt.Println("error reading directory:", err) //if directory is not read properly print error message return } for _, fileInfos := range fileInfos { //fmt.Println("img dir:", fileInfos.Name()) //print the files from directory mapPngAll[fileInfos.Name()] = 1 } } // 获取Markdown文件和img文件存储的路径 func getConfigFile(filepath string) { file, err := os.ReadFile(filepath) if err != nil { log.Fatal(err) } err = json.Unmarshal(file, &configForMd) if err != nil { log.Fatal(err) } fmt.Println("mddir:", configForMd.MDdir) fmt.Println("pngdir:", configForMd.ImgDir) configForMd.MDdir += "\\" configForMd.ImgDir += "\\" } // 将寻找到的在使用的png的文件名记录到map中 func storePngUsedfile(matchStr []string) { strlength := len(matchStr) for i := 0; i < strlength; i++ { //寻找到的字符串是”img/.*png“,比如”img/test.png“, //实际需要存储的文件名是”test.png“, //所以实际存储的字符串要去除前四个字符,实际存储是matchStr[i][4:] mapPngUsedString[matchStr[i][4:]] = 1 } } // 使用正则表达式,寻找png的路径和文件名,并通过match数组返回 func regFindImg(content string) (match []string, err error) { re := regexp.MustCompile("img/.*png") found := re.FindAllString(content, -1) if found == nil { //fmt.Printf("no match found\n") return nil, err } //fmt.Printf("------found: %q\n", found) return found, nil }
1、推荐的md和img的存储结构如下,
|–任意一个目录,假设为A
~~~
|—001.md
~~~
|—002.md
~~~
****
~~~
|—xxx.md
~~~
|—img
~~~~~~
|— used001.png
~~~~~~
|— used002.png
最好将md的图片存储路径放到当前目录的img目录,
如果img存储了其他路径B dir的md文件的图片,就无法知道B路径使用了哪些图片,就会误删除B路径的md文件存储在A路径的img图片。
2、Marktext设置md的图片存储路径的设置如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。