1 Star 0 Fork 0

shift0ogg/xmind-counter

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
xmind-counter.go 7.07 KB
一键复制 编辑 原始数据 按行查看 历史
ylliu 提交于 2025-05-13 21:37 +08:00 . 1.【d】必须单独一行作为第四行
package main
import (
"archive/zip"
"encoding/json"
"flag"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"gitee.com/shift0ogg/xmind-counter/internal"
)
func fileExists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
}
return !info.IsDir() // 确保不是目录
}
var (
inputFile string
outputFile string
help bool
delNum bool
Version string
CommitID string
BuildTime string
)
func main() {
// 输入和输出文件路径
flag.StringVar(&inputFile, "i", "", "输入XMind文件路径")
flag.StringVar(&outputFile, "o", "", "输出XMind文件路径")
flag.BoolVar(&help, "h", false, "显示帮助信息")
flag.BoolVar(&delNum, "d", false, "是否去掉[d]")
versionFlag := flag.Bool("version", false, "Print version information")
flag.Parse()
if *versionFlag {
fmt.Printf("Version: %s\nCommit: %s\nBuild Time: %s\n", Version, CommitID, BuildTime)
os.Exit(0)
}
// 2. 处理帮助信息
if help || inputFile == "" || outputFile == "" {
fmt.Println("usage :")
fmt.Println(" xmind-counter -i <input file> -o <output file>")
fmt.Println(" for example: xmind-counter -i ii.xmind -o oo.xmind")
fmt.Println("args:")
flag.PrintDefaults()
return
}
if fileExists(inputFile) {
} else {
fmt.Println("input File does not exist.")
return
}
// 1. 解压XMind文件
tempDir, err := unzipXMind(inputFile)
if err != nil {
fmt.Printf("处理 XMind文件失败: %v\n", err)
return
}
defer os.RemoveAll(tempDir)
// 2. 读取并解析content.json
contentPath := filepath.Join(tempDir, "content.json")
content, err := os.ReadFile(contentPath)
if err != nil {
fmt.Printf("读取content.json失败: %v\n", err)
return
}
var roots []internal.RootElement
err = json.Unmarshal(content, &roots)
if err != nil {
fmt.Printf("解析content.json失败: %v\n", err)
return
}
// 3. 统计每个节点的子孙节点数量并更新标题
for i := range roots {
processNode(&roots[i].RootTopic)
}
// 4. 将修改后的内容写回content.json
updatedContent, err := json.MarshalIndent(roots, "", " ")
if err != nil {
fmt.Printf("序列化修改后的content.json失败: %v\n", err)
return
}
err = os.WriteFile(contentPath, updatedContent, 0644)
if err != nil {
fmt.Printf("写入修改后的content.json失败: %v\n", err)
return
}
// 5. 重新打包为新的XMind文件
err = zipXMind(tempDir, outputFile)
if err != nil {
fmt.Printf("创建新的XMind文件失败: %v\n", err)
return
}
fmt.Printf("处理完成,已保存为: %s\n", outputFile)
}
// 解压XMind文件到临时目录
func unzipXMind(src string) (string, error) {
tempDir, err := os.MkdirTemp("", "xmind")
if err != nil {
return "", err
}
r, err := zip.OpenReader(src)
if err != nil {
return "", err
}
defer r.Close()
for _, f := range r.File {
path := filepath.Join(tempDir, f.Name)
if f.FileInfo().IsDir() {
os.MkdirAll(path, os.ModePerm)
continue
}
if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
return "", err
}
outFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return "", err
}
rc, err := f.Open()
if err != nil {
outFile.Close()
return "", err
}
_, err = io.Copy(outFile, rc)
outFile.Close()
rc.Close()
if err != nil {
return "", err
}
}
return tempDir, nil
}
func removeBrackets(s string) string {
var result strings.Builder
inBracket := false
for _, char := range s {
if char == '[' {
inBracket = true
continue
}
if char == ']' {
inBracket = false
continue
}
if !inBracket {
result.WriteRune(char)
}
}
return result.String()
}
// 处理节点,统计子孙节点数量并更新标题
func processNode(node *internal.Node) int {
total := 0
// 递归处理所有子节点
//上一级节点形状是方框并且填充色是无色,则本节点是填充色为桃红色,本节点下面的所有子节点填充颜色设为蓝色;
for i := range node.Children.Attached {
//上一级节点形状是方框并且填充色桃红色,本节点下面的所有子节点填充颜色设为蓝色;
if node.Style.Properties.Svg_fill == "#8EDDF9" {
node.Children.Attached[i].Style.Properties.Svg_fill = "#8EDDF9"
node.Children.Attached[i].Style.Properties.Fill_pattern = "solid"
}
if strings.Contains(node.Style.Properties.Shape_class, "ellipse") && node.Style.Properties.Svg_fill == "#F5E0F1" {
node.Children.Attached[i].Style.Properties.Svg_fill = "#8EDDF9"
node.Children.Attached[i].Style.Properties.Fill_pattern = "solid"
}
//上一级节点形状是方框并且填充色是无色,本节点是椭圆,则本节点是填充色为桃红色
if strings.Contains(node.Style.Properties.Shape_class, "rect") &&
strings.Contains(node.Children.Attached[i].Style.Properties.Shape_class, "ellipse") &&
(node.Style.Properties.Fill_pattern == "none" || strings.Contains(node.Style.Properties.Svg_fill, "#FFFFFF")) {
node.Children.Attached[i].Style.Properties.Svg_fill = "#F5E0F1"
node.Children.Attached[i].Style.Properties.Fill_pattern = "solid"
//fmt.Print(node.Children.Attached[i].Title)
}
total += processNode(&node.Children.Attached[i]) + 1
}
// 更新节点标题,添加计数
if strings.Contains(node.Style.Properties.Shape_class, "rect") { //节点形状如果是方框,则将该节点的字体改为10号字;
node.Style.Properties.Fo_font_size = "10"
}
if strings.Contains(node.Style.Properties.Shape_class, "ellipse") { //节点形状如果是椭圆,则将该节点的字体改为8号字
node.Style.Properties.Fo_font_size = "8"
}
//先去掉[...]
node.Title = removeBrackets(node.Title)
//4、节点中的文字如果小于三行,则在最前面增加换行符号,让它成为三行文字;
for len(strings.Split(node.Title, "\n")) <= 2 {
node.Title = "\n" + node.Title
}
//节点中的文字如果大于三行,则从后面依次删减换行符,让它成为三行文字;
dd := strings.Split(node.Title, "\n")
if len(dd) > 2 {
node.Title = strings.Join(dd[0:3], "\n") + strings.Join(dd[3:], "")
}
//检查是否已经添加过计数 每个节点(包括尾端节点)增第四行文字“[d]“,d是该节点子孙节点的个数,文字居中。
if !delNum {
node.Title = fmt.Sprintf("%s\n[%d]", node.Title, total)
}
node.Style.Properties.Fo_text_align = "center"
return total
}
// 将临时目录打包为XMind文件
func zipXMind(src string, dest string) error {
zipFile, err := os.Create(dest)
if err != nil {
return err
}
defer zipFile.Close()
zipWriter := zip.NewWriter(zipFile)
defer zipWriter.Close()
err = filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
relPath, err := filepath.Rel(src, path)
if err != nil {
return err
}
if info.IsDir() {
_, err = zipWriter.Create(relPath + "/")
return err
}
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
zipEntry, err := zipWriter.Create(relPath)
if err != nil {
return err
}
_, err = io.Copy(zipEntry, file)
return err
})
return err
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/shift0ogg/xmind-counter.git
git@gitee.com:shift0ogg/xmind-counter.git
shift0ogg
xmind-counter
xmind-counter
f42e9cfc2de0

搜索帮助