diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/Conf.go b/Conf.go new file mode 100644 index 0000000..a9a15b3 --- /dev/null +++ b/Conf.go @@ -0,0 +1,6 @@ +package main + +type Conf struct { + Excludes []string `yaml:"excludes"` + FileDir string `yaml:"fileDir"` +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..742ddde --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# MDAddTag +- 为你的md文件按照目录结构添加tag. +- 如果你刚从传统的目录结构的笔记软件如:OneNote, EverNote, 等等。转移到双链笔记应用如:LogSeq, +Obsidian, 那你可能也有和我一样的问题在;在目录结构应用中辛苦维护的结构关系全部不见。在图谱中看不到关联关系, +也不能享受方便的双链跳转功能。因此你就需要这个工具来帮助你为你的每个笔记添加所属目录的标签 +## 举例 +你有下面的目录结构的文件 +```text +├─docker +│ │ │ ├─Dockerfile +│ │ │ │ ├─ARG +│ │ │ │ └─RUN +│ │ │ └─Nano Server + +``` +转换以后, 在ARG文件中的第一行会出现#Dockerfile, 如果文件夹名称有空格,则会被剔除。 +--- +--- +# MDAddTag +- Add tags to your md files based on the directory structure. +- If you have recently transitioned from traditional note-taking software with directory structures such as OneNote, EverNote, etc. to a bidirectional note-taking app like LogSeq or Obsidian, you might have encountered the same problem as me. All the structural relationships that were painstakingly maintained in the directory structure application are lost. You can't see the connections in the graph, nor can you enjoy the convenience of bidirectional linking. That's why you need this tool to help you add tags based on the directory structure for each of your notes. +Example + +Suppose you have the following directory structure for your files: +```text + +├─docker +│ │ │ ├─Dockerfile +│ │ │ │ ├─ARG +│ │ │ │ └─RUN +│ │ │ └─Nano Server +``` +After the conversion, the first line in the ARG file will have the tag "#Dockerfile". If a folder name has a space, it will be excluded. diff --git a/conf.yml b/conf.yml new file mode 100644 index 0000000..6598a91 --- /dev/null +++ b/conf.yml @@ -0,0 +1,7 @@ +excludes: + - "assets" + - "journals" + - "logseq" + - "pages" + - "whiteboards" +fileDir: "E:\Archive\Note1" \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..aa5466a --- /dev/null +++ b/go.mod @@ -0,0 +1,17 @@ +module MDAddTag + +go 1.21 + +require ( + github.com/gookit/goutil v0.6.14 + github.com/shurcooL/markdownfmt v0.0.0-20210117162146-75134924a9fd + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/russross/blackfriday v1.6.0 // indirect + github.com/shurcooL/go v0.0.0-20230706063926-5fe729b41b3a // indirect + golang.org/x/text v0.13.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..9f505a2 --- /dev/null +++ b/go.sum @@ -0,0 +1,28 @@ +github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= +github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= +github.com/gookit/goutil v0.6.14 h1:96elyOG4BvVoDaiT7vx1vHPrVyEtFfYlPPBODR0/FGQ= +github.com/gookit/goutil v0.6.14/go.mod h1:YyDBddefmjS+mU2PDPgCcjVzTDM5WgExiDv5ZA/b8I8= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= +github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= +github.com/shurcooL/go v0.0.0-20230706063926-5fe729b41b3a h1:ZHfoO7ZJhws9NU1kzZhStUnnVQiPtDe1PzpUnc6HirU= +github.com/shurcooL/go v0.0.0-20230706063926-5fe729b41b3a/go.mod h1:DNrlr0AR9NsHD/aoc2pPeu4uSBZ/71yCHkR42yrzW3M= +github.com/shurcooL/markdownfmt v0.0.0-20210117162146-75134924a9fd h1:bpS1EjAotX7LeZwlx4tSRd6W3D639QXr6Y3+uhDHKoU= +github.com/shurcooL/markdownfmt v0.0.0-20210117162146-75134924a9fd/go.mod h1:Y3QM23ahLei1QaMBScz4YZbWktsBlf2A2DT2Yw2Ts68= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go new file mode 100644 index 0000000..3f0ffae --- /dev/null +++ b/main.go @@ -0,0 +1,94 @@ +package main + +import ( + "bytes" + "github.com/gookit/goutil/arrutil" + "github.com/gookit/goutil/fsutil" + markdown2 "github.com/shurcooL/markdownfmt/markdown" + "gopkg.in/yaml.v3" + "os" + "path/filepath" + "strings" +) + +var confs *Conf +var outFolderName string +var oriFolderName string + +func main() { + confs = readConf() + exists := fsutil.IsDir(confs.FileDir) + if !exists { + panic("the dir is not exist in conf, please check it") + } + fsutil.QuietRemove(filepath.Dir(confs.FileDir)) + oriFolderName = filepath.Base(confs.FileDir) + outFolderName = oriFolderName + "_processed" + //fsutil.Mkdir(filepath.Dir(confs.FileDir)+outFolderName, 0755) + err := filepath.WalkDir(confs.FileDir, visit) + if err != nil { + return + } + return +} + +func visit(path string, d os.DirEntry, err error) error { + + if d.IsDir() && arrutil.Contains(confs.Excludes, filepath.Base(path)) { + return filepath.SkipDir + } else if filepath.Ext(path) == ".md" { + handleContent(path) + } + return err +} + +func handleContent(path string) { + + file, err := os.ReadFile(path) + if err != nil { + println("read file fail", err) + return + } + process, err := markdown2.Process(path, file, nil) + if err != nil { + println("markdown format fail", err) + return + } + filename := strings.Replace(path, oriFolderName, outFolderName, 1) + err = os.MkdirAll(filepath.Dir(filename), 0755) + if err != nil { + println("create new Dir fail", err) + return + } + var buf = bytes.Buffer{} + buf.Write([]byte("#" + strings.ReplaceAll(filepath.Base(filepath.Dir(path)), " ", "") + "\n")) + buf.Write(process) + err = os.WriteFile(filename, buf.Bytes(), 0755) + if err != nil { + println("write file fail", err) + recover() + return + } + //println(process) +} + +func readConf() *Conf { + var conf = Conf{} + executable, err := os.Executable() + if err != nil { + return &Conf{} + } + dir := filepath.Dir(executable) + file, err := os.ReadFile(dir + "./conf.yml") + if err != nil { + println("read conf file fail "+ + "", err) + return &Conf{} + } + err = yaml.Unmarshal(file, &conf) + if err != nil { + println("parse conf fail", err) + return &Conf{} + } + return &conf +}