A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
at lambda-fork/main 133 lines 4.6 kB view raw
1// SiYuan - Refactor your thinking 2// Copyright (c) 2020-present, b3log.org 3// 4// This program is free software: you can redistribute it and/or modify 5// it under the terms of the GNU Affero General Public License as published by 6// the Free Software Foundation, either version 3 of the License, or 7// (at your option) any later version. 8// 9// This program is distributed in the hope that it will be useful, 10// but WITHOUT ANY WARRANTY; without even the implied warranty of 11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12// GNU Affero General Public License for more details. 13// 14// You should have received a copy of the GNU Affero General Public License 15// along with this program. If not, see <https://www.gnu.org/licenses/>. 16 17package util 18 19import ( 20 "bytes" 21 "io" 22 "strings" 23 24 "github.com/facette/natsort" 25 "golang.org/x/text/encoding/simplifiedchinese" 26 "golang.org/x/text/transform" 27) 28 29func NaturalCompare(str1, str2 string) bool { 30 str1 = RemoveEmojiInvisible(str1) 31 str2 = RemoveEmojiInvisible(str2) 32 return natsort.Compare(str1, str2) 33} 34 35func EmojiPinYinCompare(str1, str2 string) bool { 36 str1_ := strings.TrimSpace(RemoveEmojiInvisible(str1)) 37 str2_ := strings.TrimSpace(RemoveEmojiInvisible(str2)) 38 if str1_ == str2_ && 0 == len(str1_) { 39 // 全部都是 emoji 的情况按 emoji 字符串排序 40 return strings.Compare(str1, str2) < 0 41 } 42 return PinYinCompare(str1, str2) 43} 44 45func PinYinCompare(str1, str2 string) bool { 46 str1 = RemoveEmojiInvisible(str1) 47 str2 = RemoveEmojiInvisible(str2) 48 49 // Doc tree, backlinks, tags and templates ignores case when sorting alphabetically by name https://github.com/siyuan-note/siyuan/issues/8360 50 str1 = strings.ToLower(str1) 51 str2 = strings.ToLower(str2) 52 53 a, _ := UTF82GBK(str1) 54 b, _ := UTF82GBK(str2) 55 bLen := len(b) 56 for idx, chr := range a { 57 if idx > bLen-1 { 58 return false 59 } 60 if chr != b[idx] { 61 return chr < b[idx] 62 } 63 } 64 return true 65} 66 67func PinYinCompare4FileTree(str1, str2 string) bool { 68 // 文档树字母排序不复用 PinYinCompare 而是单独实现 69 // Improve doc tree Name Alphabet sorting https://github.com/siyuan-note/siyuan/issues/14773 70 71 str1 = RemoveEmojiInvisible(str1) 72 str1 = strings.TrimSuffix(str1, ".sy") 73 str2 = RemoveEmojiInvisible(str2) 74 str2 = strings.TrimSuffix(str2, ".sy") 75 76 // Doc tree, backlinks, tags and templates ignores case when sorting alphabetically by name https://github.com/siyuan-note/siyuan/issues/8360 77 str1 = strings.ToLower(str1) 78 str2 = strings.ToLower(str2) 79 80 a, _ := UTF82GBK(str1) 81 b, _ := UTF82GBK(str2) 82 83 // 长度相等的情况下,直接比较字节数组 84 if len(a) == len(b) { 85 return bytes.Compare(a, b) < 0 86 } 87 88 // 长度不相等的情况下,比较前面相等的部分 89 if len(a) < len(b) { 90 if 0 == bytes.Compare(a, b[:len(a)]) { // 前面相等的情况下短的在前 91 return true 92 } 93 return bytes.Compare(a, b[:len(a)]) < 0 94 } 95 if 0 == bytes.Compare(a[:len(b)], b) { 96 return false 97 } 98 return bytes.Compare(a[:len(b)], b) < 0 99} 100 101// UTF82GBK transform UTF8 rune into GBK byte array. 102func UTF82GBK(src string) ([]byte, error) { 103 GB18030 := simplifiedchinese.All[0] 104 return io.ReadAll(transform.NewReader(bytes.NewReader([]byte(src)), GB18030.NewEncoder())) 105} 106 107// GBK2UTF8 transform GBK byte array into UTF8 string. 108func GBK2UTF8(src []byte) (string, error) { 109 GB18030 := simplifiedchinese.All[0] 110 bytes, err := io.ReadAll(transform.NewReader(bytes.NewReader(src), GB18030.NewDecoder())) 111 return string(bytes), err 112} 113 114const ( 115 SortModeNameASC = iota // 0:文件名字母升序 116 SortModeNameDESC // 1:文件名字母降序 117 SortModeUpdatedASC // 2:文件更新时间升序 118 SortModeUpdatedDESC // 3:文件更新时间降序 119 SortModeAlphanumASC // 4:文件名自然数升序 120 SortModeAlphanumDESC // 5:文件名自然数降序 121 SortModeCustom // 6:自定义排序 122 SortModeRefCountASC // 7:引用数升序 123 SortModeRefCountDESC // 8:引用数降序 124 SortModeCreatedASC // 9:文件创建时间升序 125 SortModeCreatedDESC // 10:文件创建时间降序 126 SortModeSizeASC // 11:文件大小升序 127 SortModeSizeDESC // 12:文件大小降序 128 SortModeSubDocCountASC // 13:子文档数升序 129 SortModeSubDocCountDESC // 14:子文档数降序 130 SortModeFileTree // 15:使用文档树排序规则 131 132 SortModeUnassigned = 256 // 256:未指定排序规则,按照笔记本优先于文档树获取排序规则 133)