diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /indexing/zhmakeindex/stroke_collator.go |
Initial commit
Diffstat (limited to 'indexing/zhmakeindex/stroke_collator.go')
-rw-r--r-- | indexing/zhmakeindex/stroke_collator.go | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/indexing/zhmakeindex/stroke_collator.go b/indexing/zhmakeindex/stroke_collator.go new file mode 100644 index 0000000000..43f87e47d9 --- /dev/null +++ b/indexing/zhmakeindex/stroke_collator.go @@ -0,0 +1,89 @@ +package main + +import ( + "strconv" + "unicode" + "unicode/utf8" + + "github.com/leo-liu/zhmakeindex/CJK" +) + +// 汉字按笔画排序,汉字按笔画分组排在英文字母组后面 +type StrokeIndexCollator struct{} + +func (_ StrokeIndexCollator) InitGroups(style *OutputStyle) []IndexGroup { + // 分组:符号、数字、字母 A..Z、笔划 1..MAX_STROKE + groups := make([]IndexGroup, 2+26+CJK.MAX_STROKE) + if style.headings_flag > 0 { + groups[0].name = style.symhead_positive + groups[1].name = style.numhead_positive + for alph, i := 'A', 2; alph <= 'Z'; alph++ { + groups[i].name = string(alph) + i++ + } + } else if style.headings_flag < 0 { + groups[0].name = style.symhead_negative + groups[1].name = style.numhead_negative + for alph, i := 'a', 2; alph <= 'z'; alph++ { + groups[i].name = string(alph) + i++ + } + } + for stroke, i := 1, 2+26; stroke <= CJK.MAX_STROKE; stroke++ { + groups[i].name = style.stroke_prefix + strconv.Itoa(stroke) + style.stroke_suffix + i++ + } + return groups +} + +// 取得分组 +func (_ StrokeIndexCollator) Group(entry *IndexEntry) int { + first, _ := utf8.DecodeRuneInString(entry.level[0].key) + first = unicode.ToLower(first) + switch { + case IsNumString(entry.level[0].key): + return 1 + case 'a' <= first && first <= 'z': + return 2 + int(first) - 'a' + case len(CJK.Strokes[first]) > 0: + return 2 + 26 + (len(CJK.Strokes[first]) - 1) + default: + // 符号组 + return 0 + } +} + +// 按汉字笔画、笔顺序比较两个字符大小 +// 笔画数不同的,短的在前;笔画数相同的,笔顺字典序;笔顺相同的,内码序 +func (_ StrokeIndexCollator) RuneCmp(a, b rune) int { + a_strokes, b_strokes := len(CJK.Strokes[a]), len(CJK.Strokes[b]) + switch { + case a_strokes == 0 && b_strokes == 0: + return RuneCmpIgnoreCases(a, b) + case a_strokes == 0 && b_strokes != 0: + return -1 + case a_strokes != 0 && b_strokes == 0: + return 1 + case a_strokes != b_strokes: + return a_strokes - b_strokes + case CJK.Strokes[a] < CJK.Strokes[b]: + return -1 + case CJK.Strokes[a] > CJK.Strokes[b]: + return 1 + default: + return int(a - b) + } +} + +// 判断是否字母或汉字 +func (_ StrokeIndexCollator) IsLetter(r rune) bool { + r = unicode.ToLower(r) + switch { + case 'a' <= r && r <= 'z': + return true + case CJK.Strokes[r] != "": + return true + default: + return false + } +} |