From 4084193c8034582dca3dad281a51962869404fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Thu, 15 Feb 2024 17:50:39 +0900 Subject: [PATCH] feat(cmd): finish --- README.md | 11 ++++++++++ cmd/main.go | 61 ++++++++++++++++++++++++++++++++++++++++++++--------- coder.go | 16 +++++++------- data.go | 19 +++++++++++++++++ radical.go | 2 +- 5 files changed, 90 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 79b6feb..93e053a 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,10 @@ 解码颜文字为汉字序列 -db string 符合规范的查询数据库位置, 不存在则会自动释放到该路径. (default "字.db") + -deloverlay int + 删除一个附加库中的字 + -delradical + 删除-r指定的部首的记录 -e string 编码汉字序列为颜文字 -f 强制解码并非由本程序生成的颜文字序列 @@ -30,8 +34,15 @@ 指定欲编辑的部首 -re string 指定部首对应的颜文字 + -stabilize int + 固定附加库中的字到主库 ``` 下面是一些用例。 +### 查询一个字的国际音标、部首、全局ID +```bash +go run cmd/main.go -i -a 哦 -p o +文字: 哦 拼音IPA: 0 ɔ 轻声 ID: 93346820784388 +``` ### 编码 > 注意: 可以指定`-nr`参数从而使编解码结果唯一。 ```bash diff --git a/cmd/main.go b/cmd/main.go index dd33e0f..bd90e65 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -21,16 +21,21 @@ func main() { noRandom := flag.Bool("nr", false, "不随机选取所有读音相近的颜文字") showhelp := flag.Bool("h", false, "显示帮助信息") forcedecode := flag.Bool("f", false, "强制解码并非由本程序生成的颜文字序列") + stabilize := flag.Int64("stabilize", 0, "固定附加库中的字到主库") + deloverlay := flag.Int64("deloverlay", 0, "删除一个附加库中的字") + delradical := flag.Bool("delradical", false, "删除-r指定的部首的记录") flag.Parse() + defer fmt.Println("程序处理结束") if *showhelp { - fmt.Println("用法: [-h|f|nr] [-db 字.db] [-d 🌹😺‎🐴‫👩] [-e 好] 形声字选择1 形声字选择2 ...") + fmt.Println("用法: [-h|f|nr] [-db 字.db] [-d 🌹😺‎🐴‫👩] [-e 好] 形声字选择1 形声字选择2 ...") // nolint: go-staticcheck flag.PrintDefaults() return } emozi.EmoziDatabasePath = *dbpath coder, err := emozi.NewCoder(time.Minute) if err != nil { - panic(err) + fmt.Println("ERROR: emozi.NewCoder:", err) + return } defer coder.Close() if *isencode != "" { @@ -39,13 +44,15 @@ func main() { for i, ns := range rem { n, err := strconv.Atoi(ns) if err != nil { - panic("第" + strconv.Itoa(i+1) + "个形声字参数 '" + ns + "' 非法") + fmt.Println("ERROR: 第" + strconv.Itoa(i+1) + "个形声字参数 '" + ns + "' 非法") + return } lst[i] = n } es, lst, err := coder.Encode(!*noRandom, *isencode, lst...) if err != nil { - panic(err) + fmt.Println("ERROR: coder.Encode:", err) + return } fmt.Println("编码结果:", string(es)) if len(lst) > 0 && len(rem) == 0 { @@ -59,7 +66,8 @@ func main() { case err == emozi.ErrInvalidEmoziString: fmt.Println("解码结果: 非本程序直接生成的颜文字序列或序列经过人为修改") case err != nil: - panic(err) + fmt.Println("ERROR: coder.Decode:", err) + return default: fmt.Println("解码结果:", s) } @@ -67,28 +75,61 @@ func main() { if *addoverlay != "" && *pinyinfull != "" && *radical != "" { id, desc, err := coder.AddCharOverlay(*addoverlay, *radical, "", *pinyinfull) if err != nil { - panic(err) + fmt.Println("ERROR: coder.AddCharOverlay:", err) + return } fmt.Println("已添加汉字:", *addoverlay, "读音:", desc, "部首:", *radical, "ID:", id) } if *radical != "" && *radicalemozi != "" { rr := []rune(*radical) if len(rr) != 1 { - panic("非法部首 '" + *radical + "': 长度为" + strconv.Itoa(len(rr))) + fmt.Println("ERROR: 非法部首 '" + *radical + "': 长度为" + strconv.Itoa(len(rr))) + return } - err = coder.AddRadicalOverlay(rr[0], *radicalemozi) + err = coder.AddRadical(rr[0], *radicalemozi) if err != nil { - panic(err) + fmt.Println("ERROR: coder.AddRadical:", err) + return } fmt.Println("已添加部首:", *radical, "颜文字:", *radicalemozi) } if *getglobalid && *addoverlay != "" && *pinyinfull != "" { sm, ym, sd, err := emozi.SplitPinyin(*pinyinfull) if err != nil { - panic(err) + fmt.Println("ERROR: coder.SplitPinyin:", err) + return } r := []rune(*addoverlay)[0] id, _ := emozi.CharGlobalID(r, *pinyinfull) fmt.Println("文字:", string(r), "拼音IPA:", sm, ym, sd, "ID:", id) } + if *stabilize != 0 { + desc, err := coder.StabilizeCharFromOverlay(*stabilize) + if err != nil { + fmt.Println("ERROR: coder.StabilizeCharFromOverlay:", err) + return + } + fmt.Println("固定到主库成功:", desc) + } + if *delradical && *radical != "" { + rr := []rune(*radical) + if len(rr) != 1 { + fmt.Println("ERROR: 非法部首 '" + *radical + "': 长度为" + strconv.Itoa(len(rr))) + return + } + err = coder.DelRadical(rr[0]) + if err != nil { + fmt.Println("ERROR: coder.DelRadical:", err) + return + } + fmt.Println("删除部首", string(rr[0]), "成功") + } + if *deloverlay != 0 { + err = coder.DelCharOverlay(*deloverlay) + if err != nil { + fmt.Println("ERROR: coder.DelCharOverlay:", err) + return + } + fmt.Println("已删除汉字ID:", *deloverlay) + } } diff --git a/coder.go b/coder.go index cf46565..328234f 100644 --- a/coder.go +++ b/coder.go @@ -307,20 +307,20 @@ func (c *Coder) ChangeCharOverlay(oldw, oldr, oldf, neww, newr, newf string) (in } // StabilizeCharFromOverlay 将附加库中的一项固定到主库 -func (c *Coder) StabilizeCharFromOverlay(id int64) error { +func (c *Coder) StabilizeCharFromOverlay(id int64) (string, error) { x := 字表{} q := "WHERE ID=" + strconv.FormatInt(id, 10) c.mu.Lock() defer c.mu.Unlock() err := c.db.Find(附字表名, &x, q) if err != nil { - return err + return "", err } err = c.db.Insert(主字表名, &x) if err != nil { - return err + return x.String(), err } - return c.db.Del(附字表名, q) + return x.String(), c.db.Del(附字表名, q) } // DelChar 删除主库的一个字 @@ -337,15 +337,15 @@ func (c *Coder) DelCharOverlay(id int64) error { return c.db.Del(附字表名, "WHERE ID="+strconv.FormatInt(id, 10)) } -// AddRadicalOverlay 添加一个部首 -func (c *Coder) AddRadicalOverlay(r rune, e string) error { +// AddRadical 添加一个部首 +func (c *Coder) AddRadical(r rune, e string) error { c.mu.Lock() defer c.mu.Unlock() return c.db.InsertUnique(部首表名, &部首表{R: r, E: e}) } -// DelRadicalOverlay 删除一个部首 -func (c *Coder) DelRadicalOverlay(r rune) error { +// DelRadical 删除一个部首 +func (c *Coder) DelRadical(r rune) error { c.mu.Lock() defer c.mu.Unlock() return c.db.Del(部首表名, "WHERE R="+strconv.Itoa(int(r))) diff --git a/data.go b/data.go index 195f0ae..2820de8 100644 --- a/data.go +++ b/data.go @@ -37,6 +37,25 @@ type 字表 struct { F string } +func (z *字表) String() string { + sb := strings.Builder{} + sb.WriteString("#") + sb.WriteString(strconv.FormatInt(z.ID, 10)) + sb.WriteByte(' ') + sb.WriteRune(z.W) + sb.WriteString(" [") + sb.WriteString(z.S.String()) + sb.WriteString(z.Y.String()) + sb.WriteString(z.T.String()) + sb.WriteString("] 从") + sb.WriteRune(z.R) + sb.WriteByte(' ') + sb.WriteString(z.P) + sb.WriteByte(' ') + sb.WriteString(z.F) + return sb.String() +} + // CharGlobalID 计算全局唯一字表ID func CharGlobalID(w rune, f string) (int64, error) { p := 去调(f) diff --git a/radical.go b/radical.go index 511b375..210a57a 100644 --- a/radical.go +++ b/radical.go @@ -237,7 +237,7 @@ var 部首后备 = map[rune]string{ '貝': string(空), '邑': string(空), '𨛜': string(空), - '日': string(空), + '日': "🌞", '旦': string(空), '倝': string(空), '㫃': string(空),